summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorJosé Pekkarinen <jose.pekkarinen@nokia.com>2016-04-11 10:41:07 +0300
committerJosé Pekkarinen <jose.pekkarinen@nokia.com>2016-04-13 08:17:18 +0300
commite09b41010ba33a20a87472ee821fa407a5b8da36 (patch)
treed10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/scsi/megaraid
parentf93b97fd65072de626c074dbe099a1fff05ce060 (diff)
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page. During the rebasing, the following patch collided: Force tick interrupt and get rid of softirq magic(I70131fb85). Collisions have been removed because its logic was found on the source already. Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769 Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/scsi/megaraid')
-rw-r--r--kernel/drivers/scsi/megaraid/megaraid_sas.h400
-rw-r--r--kernel/drivers/scsi/megaraid/megaraid_sas_base.c1707
-rw-r--r--kernel/drivers/scsi/megaraid/megaraid_sas_fp.c53
-rw-r--r--kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c1013
-rw-r--r--kernel/drivers/scsi/megaraid/megaraid_sas_fusion.h317
5 files changed, 1887 insertions, 1603 deletions
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas.h b/kernel/drivers/scsi/megaraid/megaraid_sas.h
index 14e5c7cea..c0f7c8ce5 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas.h
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas.h
@@ -35,7 +35,8 @@
/*
* MegaRAID SAS Driver meta data
*/
-#define MEGASAS_VERSION "06.806.08.00-rc1"
+#define MEGASAS_VERSION "06.808.16.00-rc1"
+#define MEGASAS_RELDATE "Oct. 8, 2015"
/*
* Device IDs
@@ -51,6 +52,10 @@
#define PCI_DEVICE_ID_LSI_PLASMA 0x002f
#define PCI_DEVICE_ID_LSI_INVADER 0x005d
#define PCI_DEVICE_ID_LSI_FURY 0x005f
+#define PCI_DEVICE_ID_LSI_INTRUDER 0x00ce
+#define PCI_DEVICE_ID_LSI_INTRUDER_24 0x00cf
+#define PCI_DEVICE_ID_LSI_CUTLASS_52 0x0052
+#define PCI_DEVICE_ID_LSI_CUTLASS_53 0x0053
/*
* Intel HBA SSDIDs
@@ -61,6 +66,14 @@
#define MEGARAID_INTEL_RS3MC044_SSDID 0x9381
#define MEGARAID_INTEL_RS3WC080_SSDID 0x9341
#define MEGARAID_INTEL_RS3WC040_SSDID 0x9343
+#define MEGARAID_INTEL_RMS3BC160_SSDID 0x352B
+
+/*
+ * Intruder HBA SSDIDs
+ */
+#define MEGARAID_INTRUDER_SSDID1 0x9371
+#define MEGARAID_INTRUDER_SSDID2 0x9390
+#define MEGARAID_INTRUDER_SSDID3 0x9370
/*
* Intel HBA branding
@@ -77,6 +90,8 @@
"Intel(R) RAID Controller RS3WC080"
#define MEGARAID_INTEL_RS3WC040_BRANDING \
"Intel(R) RAID Controller RS3WC040"
+#define MEGARAID_INTEL_RMS3BC160_BRANDING \
+ "Intel(R) Integrated RAID Module RMS3BC160"
/*
* =====================================
@@ -153,6 +168,9 @@
#define MFI_FRAME_DIR_BOTH 0x0018
#define MFI_FRAME_IEEE 0x0020
+/* Driver internal */
+#define DRV_DCMD_POLLED_MODE 0x1
+
/*
* Definition for cmd_status
*/
@@ -269,6 +287,16 @@ enum MFI_STAT {
MFI_STAT_INVALID_STATUS = 0xFF
};
+enum mfi_evt_class {
+ MFI_EVT_CLASS_DEBUG = -2,
+ MFI_EVT_CLASS_PROGRESS = -1,
+ MFI_EVT_CLASS_INFO = 0,
+ MFI_EVT_CLASS_WARNING = 1,
+ MFI_EVT_CLASS_CRITICAL = 2,
+ MFI_EVT_CLASS_FATAL = 3,
+ MFI_EVT_CLASS_DEAD = 4
+};
+
/*
* Crash dump related defines
*/
@@ -360,6 +388,8 @@ enum MR_EVT_ARGS {
MR_EVT_ARGS_GENERIC,
};
+
+#define SGE_BUFFER_SIZE 4096
/*
* define constants for device list query options
*/
@@ -390,6 +420,7 @@ enum MR_LD_QUERY_TYPE {
#define MR_EVT_FOREIGN_CFG_IMPORTED 0x00db
#define MR_EVT_LD_OFFLINE 0x00fc
#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED 0x0152
+#define MR_EVT_CTRL_PROP_CHANGED 0x012f
enum MR_PD_STATE {
MR_PD_STATE_UNCONFIGURED_GOOD = 0x00,
@@ -408,7 +439,7 @@ enum MR_PD_STATE {
* defines the physical drive address structure
*/
struct MR_PD_ADDRESS {
- u16 deviceId;
+ __le16 deviceId;
u16 enclDeviceId;
union {
@@ -433,8 +464,8 @@ struct MR_PD_ADDRESS {
* defines the physical drive list structure
*/
struct MR_PD_LIST {
- u32 size;
- u32 count;
+ __le32 size;
+ __le32 count;
struct MR_PD_ADDRESS addr[1];
} __packed;
@@ -451,28 +482,28 @@ union MR_LD_REF {
struct {
u8 targetId;
u8 reserved;
- u16 seqNum;
+ __le16 seqNum;
};
- u32 ref;
+ __le32 ref;
} __packed;
/*
* defines the logical drive list structure
*/
struct MR_LD_LIST {
- u32 ldCount;
- u32 reserved;
+ __le32 ldCount;
+ __le32 reserved;
struct {
union MR_LD_REF ref;
u8 state;
u8 reserved[3];
- u64 size;
+ __le64 size;
} ldList[MAX_LOGICAL_DRIVES_EXT];
} __packed;
struct MR_LD_TARGETID_LIST {
- u32 size;
- u32 count;
+ __le32 size;
+ __le32 count;
u8 pad[3];
u8 targetId[MAX_LOGICAL_DRIVES_EXT];
};
@@ -553,7 +584,7 @@ struct megasas_ctrl_prop {
} OnOffProperties;
u8 autoSnapVDSpace;
u8 viewSpace;
- u16 spinDownTime;
+ __le16 spinDownTime;
u8 reserved[24];
} __packed;
@@ -567,10 +598,10 @@ struct megasas_ctrl_info {
*/
struct {
- u16 vendor_id;
- u16 device_id;
- u16 sub_vendor_id;
- u16 sub_device_id;
+ __le16 vendor_id;
+ __le16 device_id;
+ __le16 sub_vendor_id;
+ __le16 sub_device_id;
u8 reserved[24];
} __attribute__ ((packed)) pci;
@@ -611,8 +642,8 @@ struct megasas_ctrl_info {
/*
* List of components residing in flash. All str are null terminated
*/
- u32 image_check_word;
- u32 image_component_count;
+ __le32 image_check_word;
+ __le32 image_component_count;
struct {
@@ -629,7 +660,7 @@ struct megasas_ctrl_info {
* empty if a flash operation has not occurred. All stings are null
* terminated
*/
- u32 pending_image_component_count;
+ __le32 pending_image_component_count;
struct {
@@ -662,39 +693,39 @@ struct megasas_ctrl_info {
} __attribute__ ((packed)) hw_present;
- u32 current_fw_time;
+ __le32 current_fw_time;
/*
* Maximum data transfer sizes
*/
- u16 max_concurrent_cmds;
- u16 max_sge_count;
- u32 max_request_size;
+ __le16 max_concurrent_cmds;
+ __le16 max_sge_count;
+ __le32 max_request_size;
/*
* Logical and physical device counts
*/
- u16 ld_present_count;
- u16 ld_degraded_count;
- u16 ld_offline_count;
+ __le16 ld_present_count;
+ __le16 ld_degraded_count;
+ __le16 ld_offline_count;
- u16 pd_present_count;
- u16 pd_disk_present_count;
- u16 pd_disk_pred_failure_count;
- u16 pd_disk_failed_count;
+ __le16 pd_present_count;
+ __le16 pd_disk_present_count;
+ __le16 pd_disk_pred_failure_count;
+ __le16 pd_disk_failed_count;
/*
* Memory size information
*/
- u16 nvram_size;
- u16 memory_size;
- u16 flash_size;
+ __le16 nvram_size;
+ __le16 memory_size;
+ __le16 flash_size;
/*
* Error counters
*/
- u16 mem_correctable_error_count;
- u16 mem_uncorrectable_error_count;
+ __le16 mem_correctable_error_count;
+ __le16 mem_uncorrectable_error_count;
/*
* Cluster information
@@ -705,7 +736,7 @@ struct megasas_ctrl_info {
/*
* Additional max data transfer sizes
*/
- u16 max_strips_per_io;
+ __le16 max_strips_per_io;
/*
* Controller capabilities structures
@@ -805,7 +836,7 @@ struct megasas_ctrl_info {
* deviceInterface.portAddr, and the rest shall be
* populated in deviceInterfacePortAddr2.
*/
- u64 deviceInterfacePortAddr2[8]; /*6a0h */
+ __le64 deviceInterfacePortAddr2[8]; /*6a0h */
u8 reserved3[128]; /*6e0h */
struct { /*760h */
@@ -842,26 +873,26 @@ struct megasas_ctrl_info {
u16 reserved[6];
} pdsForRaidLevels;
- u16 maxPds; /*780h */
- u16 maxDedHSPs; /*782h */
- u16 maxGlobalHSPs; /*784h */
- u16 ddfSize; /*786h */
+ __le16 maxPds; /*780h */
+ __le16 maxDedHSPs; /*782h */
+ __le16 maxGlobalHSP; /*784h */
+ __le16 ddfSize; /*786h */
u8 maxLdsPerArray; /*788h */
u8 partitionsInDDF; /*789h */
u8 lockKeyBinding; /*78ah */
u8 maxPITsPerLd; /*78bh */
u8 maxViewsPerLd; /*78ch */
u8 maxTargetId; /*78dh */
- u16 maxBvlVdSize; /*78eh */
+ __le16 maxBvlVdSize; /*78eh */
- u16 maxConfigurableSSCSize; /*790h */
- u16 currentSSCsize; /*792h */
+ __le16 maxConfigurableSSCSize; /*790h */
+ __le16 currentSSCsize; /*792h */
char expanderFwVersion[12]; /*794h */
- u16 PFKTrialTimeRemaining; /*7A0h */
+ __le16 PFKTrialTimeRemaining; /*7A0h */
- u16 cacheMemorySize; /*7A2h */
+ __le16 cacheMemorySize; /*7A2h */
struct { /*7A4h */
#if defined(__BIG_ENDIAN_BITFIELD)
@@ -931,7 +962,7 @@ struct megasas_ctrl_info {
u8 temperatureROC; /*7C9h */
u8 temperatureCtrl; /*7CAh */
u8 reserved4; /*7CBh */
- u16 maxConfigurablePds; /*7CCh */
+ __le16 maxConfigurablePds; /*7CCh */
u8 reserved5[2]; /*0x7CDh */
@@ -969,7 +1000,12 @@ struct megasas_ctrl_info {
struct {
#if defined(__BIG_ENDIAN_BITFIELD)
- u32 reserved:12;
+ u32 reserved:7;
+ u32 useSeqNumJbodFP:1;
+ u32 supportExtendedSSCSize:1;
+ u32 supportDiskCacheSettingForSysPDs:1;
+ u32 supportCPLDUpdate:1;
+ u32 supportTTYLogCompression:1;
u32 discardCacheDuringLDDelete:1;
u32 supportSecurityonJBOD:1;
u32 supportCacheBypassModes:1;
@@ -1009,7 +1045,12 @@ struct megasas_ctrl_info {
u32 supportCacheBypassModes:1;
u32 supportSecurityonJBOD:1;
u32 discardCacheDuringLDDelete:1;
- u32 reserved:12;
+ u32 supportTTYLogCompression:1;
+ u32 supportCPLDUpdate:1;
+ u32 supportDiskCacheSettingForSysPDs:1;
+ u32 supportExtendedSSCSize:1;
+ u32 useSeqNumJbodFP:1;
+ u32 reserved:7;
#endif
} adapterOperations3;
@@ -1042,11 +1083,6 @@ struct megasas_ctrl_info {
#define VD_EXT_DEBUG 0
-enum MR_MFI_MPT_PTHR_FLAGS {
- MFI_MPT_DETACHED = 0,
- MFI_LIST_ADDED = 1,
- MFI_MPT_ATTACHED = 2,
-};
enum MR_SCSI_CMD_TYPE {
READ_WRITE_LDIO = 0,
@@ -1084,6 +1120,7 @@ enum MR_SCSI_CMD_TYPE {
#define MEGASAS_SKINNY_INT_CMDS 5
#define MEGASAS_FUSION_INTERNAL_CMDS 5
#define MEGASAS_FUSION_IOCTL_CMDS 3
+#define MEGASAS_MFI_IOCTL_CMDS 27
#define MEGASAS_MAX_MSIX_QUEUES 128
/*
@@ -1172,22 +1209,22 @@ struct megasas_register_set {
struct megasas_sge32 {
- u32 phys_addr;
- u32 length;
+ __le32 phys_addr;
+ __le32 length;
} __attribute__ ((packed));
struct megasas_sge64 {
- u64 phys_addr;
- u32 length;
+ __le64 phys_addr;
+ __le32 length;
} __attribute__ ((packed));
struct megasas_sge_skinny {
- u64 phys_addr;
- u32 length;
- u32 flag;
+ __le64 phys_addr;
+ __le32 length;
+ __le32 flag;
} __packed;
union megasas_sgl {
@@ -1210,12 +1247,12 @@ struct megasas_header {
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 timeout; /*12h */
- u32 data_xferlen; /*14h */
+ __le16 flags; /*10h */
+ __le16 timeout; /*12h */
+ __le32 data_xferlen; /*14h */
} __attribute__ ((packed));
@@ -1229,7 +1266,9 @@ union megasas_sgl_frame {
typedef union _MFI_CAPABILITIES {
struct {
#if defined(__BIG_ENDIAN_BITFIELD)
- u32 reserved:25;
+ u32 reserved:23;
+ u32 support_ext_io_size:1;
+ u32 support_ext_queue_depth:1;
u32 security_protocol_cmds_fw:1;
u32 support_core_affinity:1;
u32 support_ndrive_r1_lb:1;
@@ -1245,10 +1284,12 @@ typedef union _MFI_CAPABILITIES {
u32 support_ndrive_r1_lb:1;
u32 support_core_affinity:1;
u32 security_protocol_cmds_fw:1;
- u32 reserved:25;
+ u32 support_ext_queue_depth:1;
+ u32 support_ext_io_size:1;
+ u32 reserved:23;
#endif
} mfi_capabilities;
- u32 reg;
+ __le32 reg;
} MFI_CAPABILITIES;
struct megasas_init_frame {
@@ -1260,33 +1301,35 @@ struct megasas_init_frame {
u8 reserved_1; /*03h */
MFI_CAPABILITIES driver_operations; /*04h*/
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 reserved_3; /*12h */
- u32 data_xfer_len; /*14h */
+ __le16 flags; /*10h */
+ __le16 reserved_3; /*12h */
+ __le32 data_xfer_len; /*14h */
- u32 queue_info_new_phys_addr_lo; /*18h */
- u32 queue_info_new_phys_addr_hi; /*1Ch */
- u32 queue_info_old_phys_addr_lo; /*20h */
- u32 queue_info_old_phys_addr_hi; /*24h */
-
- u32 reserved_4[6]; /*28h */
+ __le32 queue_info_new_phys_addr_lo; /*18h */
+ __le32 queue_info_new_phys_addr_hi; /*1Ch */
+ __le32 queue_info_old_phys_addr_lo; /*20h */
+ __le32 queue_info_old_phys_addr_hi; /*24h */
+ __le32 reserved_4[2]; /*28h */
+ __le32 system_info_lo; /*30h */
+ __le32 system_info_hi; /*34h */
+ __le32 reserved_5[2]; /*38h */
} __attribute__ ((packed));
struct megasas_init_queue_info {
- u32 init_flags; /*00h */
- u32 reply_queue_entries; /*04h */
+ __le32 init_flags; /*00h */
+ __le32 reply_queue_entries; /*04h */
- u32 reply_queue_start_phys_addr_lo; /*08h */
- u32 reply_queue_start_phys_addr_hi; /*0Ch */
- u32 producer_index_phys_addr_lo; /*10h */
- u32 producer_index_phys_addr_hi; /*14h */
- u32 consumer_index_phys_addr_lo; /*18h */
- u32 consumer_index_phys_addr_hi; /*1Ch */
+ __le32 reply_queue_start_phys_addr_lo; /*08h */
+ __le32 reply_queue_start_phys_addr_hi; /*0Ch */
+ __le32 producer_index_phys_addr_lo; /*10h */
+ __le32 producer_index_phys_addr_hi; /*14h */
+ __le32 consumer_index_phys_addr_lo; /*18h */
+ __le32 consumer_index_phys_addr_hi; /*1Ch */
} __attribute__ ((packed));
@@ -1302,18 +1345,18 @@ struct megasas_io_frame {
u8 reserved_0; /*06h */
u8 sge_count; /*07h */
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 timeout; /*12h */
- u32 lba_count; /*14h */
+ __le16 flags; /*10h */
+ __le16 timeout; /*12h */
+ __le32 lba_count; /*14h */
- u32 sense_buf_phys_addr_lo; /*18h */
- u32 sense_buf_phys_addr_hi; /*1Ch */
+ __le32 sense_buf_phys_addr_lo; /*18h */
+ __le32 sense_buf_phys_addr_hi; /*1Ch */
- u32 start_lba_lo; /*20h */
- u32 start_lba_hi; /*24h */
+ __le32 start_lba_lo; /*20h */
+ __le32 start_lba_hi; /*24h */
union megasas_sgl sgl; /*28h */
@@ -1331,15 +1374,15 @@ struct megasas_pthru_frame {
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 timeout; /*12h */
- u32 data_xfer_len; /*14h */
+ __le16 flags; /*10h */
+ __le16 timeout; /*12h */
+ __le32 data_xfer_len; /*14h */
- u32 sense_buf_phys_addr_lo; /*18h */
- u32 sense_buf_phys_addr_hi; /*1Ch */
+ __le32 sense_buf_phys_addr_lo; /*18h */
+ __le32 sense_buf_phys_addr_hi; /*1Ch */
u8 cdb[16]; /*20h */
union megasas_sgl sgl; /*30h */
@@ -1354,19 +1397,19 @@ struct megasas_dcmd_frame {
u8 reserved_1[4]; /*03h */
u8 sge_count; /*07h */
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 timeout; /*12h */
+ __le16 flags; /*10h */
+ __le16 timeout; /*12h */
- u32 data_xfer_len; /*14h */
- u32 opcode; /*18h */
+ __le32 data_xfer_len; /*14h */
+ __le32 opcode; /*18h */
union { /*1Ch */
u8 b[12];
- u16 s[6];
- u32 w[3];
+ __le16 s[6];
+ __le32 w[3];
} mbox;
union megasas_sgl sgl; /*28h */
@@ -1380,22 +1423,22 @@ struct megasas_abort_frame {
u8 cmd_status; /*02h */
u8 reserved_1; /*03h */
- u32 reserved_2; /*04h */
+ __le32 reserved_2; /*04h */
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 reserved_3; /*12h */
- u32 reserved_4; /*14h */
+ __le16 flags; /*10h */
+ __le16 reserved_3; /*12h */
+ __le32 reserved_4; /*14h */
- u32 abort_context; /*18h */
- u32 pad_1; /*1Ch */
+ __le32 abort_context; /*18h */
+ __le32 pad_1; /*1Ch */
- u32 abort_mfi_phys_addr_lo; /*20h */
- u32 abort_mfi_phys_addr_hi; /*24h */
+ __le32 abort_mfi_phys_addr_lo; /*20h */
+ __le32 abort_mfi_phys_addr_hi; /*24h */
- u32 reserved_5[6]; /*28h */
+ __le32 reserved_5[6]; /*28h */
} __attribute__ ((packed));
@@ -1409,14 +1452,14 @@ struct megasas_smp_frame {
u8 reserved_2[3]; /*04h */
u8 sge_count; /*07h */
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 timeout; /*12h */
+ __le16 flags; /*10h */
+ __le16 timeout; /*12h */
- u32 data_xfer_len; /*14h */
- u64 sas_addr; /*18h */
+ __le32 data_xfer_len; /*14h */
+ __le64 sas_addr; /*18h */
union {
struct megasas_sge32 sge32[2]; /* [0]: resp [1]: req */
@@ -1436,16 +1479,16 @@ struct megasas_stp_frame {
u8 reserved_3[2]; /*05h */
u8 sge_count; /*07h */
- u32 context; /*08h */
- u32 pad_0; /*0Ch */
+ __le32 context; /*08h */
+ __le32 pad_0; /*0Ch */
- u16 flags; /*10h */
- u16 timeout; /*12h */
+ __le16 flags; /*10h */
+ __le16 timeout; /*12h */
- u32 data_xfer_len; /*14h */
+ __le32 data_xfer_len; /*14h */
- u16 fis[10]; /*18h */
- u32 stp_flags;
+ __le16 fis[10]; /*18h */
+ __le32 stp_flags;
union {
struct megasas_sge32 sge32[2]; /* [0]: resp [1]: data */
@@ -1489,18 +1532,18 @@ union megasas_evt_class_locale {
} __attribute__ ((packed));
struct megasas_evt_log_info {
- u32 newest_seq_num;
- u32 oldest_seq_num;
- u32 clear_seq_num;
- u32 shutdown_seq_num;
- u32 boot_seq_num;
+ __le32 newest_seq_num;
+ __le32 oldest_seq_num;
+ __le32 clear_seq_num;
+ __le32 shutdown_seq_num;
+ __le32 boot_seq_num;
} __attribute__ ((packed));
struct megasas_progress {
- u16 progress;
- u16 elapsed_seconds;
+ __le16 progress;
+ __le16 elapsed_seconds;
} __attribute__ ((packed));
@@ -1521,9 +1564,9 @@ struct megasas_evtarg_pd {
struct megasas_evt_detail {
- u32 seq_num;
- u32 time_stamp;
- u32 code;
+ __le32 seq_num;
+ __le32 time_stamp;
+ __le32 code;
union megasas_evt_class_locale cl;
u8 arg_type;
u8 reserved1[15];
@@ -1542,18 +1585,18 @@ struct megasas_evt_detail {
struct {
struct megasas_evtarg_ld ld;
- u64 count;
+ __le64 count;
} __attribute__ ((packed)) ld_count;
struct {
- u64 lba;
+ __le64 lba;
struct megasas_evtarg_ld ld;
} __attribute__ ((packed)) ld_lba;
struct {
struct megasas_evtarg_ld ld;
- u32 prevOwner;
- u32 newOwner;
+ __le32 prevOwner;
+ __le32 newOwner;
} __attribute__ ((packed)) ld_owner;
struct {
@@ -1610,7 +1653,7 @@ struct megasas_evt_detail {
struct {
u16 vendorId;
- u16 deviceId;
+ __le16 deviceId;
u16 subVendorId;
u16 subDeviceId;
} __attribute__ ((packed)) pci;
@@ -1630,9 +1673,9 @@ struct megasas_evt_detail {
} __attribute__ ((packed)) ecc;
u8 b[96];
- u16 s[48];
- u32 w[24];
- u64 d[12];
+ __le16 s[48];
+ __le32 w[24];
+ __le64 d[12];
} args;
char description[128];
@@ -1649,12 +1692,22 @@ struct megasas_irq_context {
u32 MSIxIndex;
};
+struct MR_DRV_SYSTEM_INFO {
+ u8 infoVersion;
+ u8 systemIdLength;
+ u16 reserved0;
+ u8 systemId[64];
+ u8 reserved[1980];
+};
+
struct megasas_instance {
- u32 *producer;
+ __le32 *producer;
dma_addr_t producer_h;
- u32 *consumer;
+ __le32 *consumer;
dma_addr_t consumer_h;
+ struct MR_DRV_SYSTEM_INFO *system_info_buf;
+ dma_addr_t system_info_h;
struct MR_LD_VF_AFFILIATION *vf_affiliation;
dma_addr_t vf_affiliation_h;
struct MR_LD_VF_AFFILIATION_111 *vf_affiliation_111;
@@ -1662,7 +1715,7 @@ struct megasas_instance {
struct MR_CTRL_HB_HOST_MEM *hb_host_mem;
dma_addr_t hb_host_mem_h;
- u32 *reply_queue;
+ __le32 *reply_queue;
dma_addr_t reply_queue_h;
u32 *crash_dump_buf;
@@ -1678,10 +1731,11 @@ struct megasas_instance {
u32 crash_dump_drv_support;
u32 crash_dump_app_support;
u32 secure_jbod_support;
+ bool use_seqnum_jbod_fp; /* Added for PD sequence */
spinlock_t crashdump_lock;
struct megasas_register_set __iomem *reg_set;
- u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
+ u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
struct megasas_pd_list local_pd_list[MEGASAS_MAX_PD];
u8 ld_ids[MEGASAS_MAX_LD_IDS];
@@ -1736,6 +1790,7 @@ struct megasas_instance {
u8 UnevenSpanSupport;
u8 supportmax256vd;
+ u8 allow_fw_scan;
u16 fw_supported_vd_count;
u16 fw_supported_pd_count;
@@ -1757,7 +1812,9 @@ struct megasas_instance {
struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES];
struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
u64 map_id;
+ u64 pd_seq_map_id;
struct megasas_cmd *map_update_cmd;
+ struct megasas_cmd *jbod_seq_cmd;
unsigned long bar;
long reset_flags;
struct mutex reset_mutex;
@@ -1768,7 +1825,9 @@ struct megasas_instance {
char mpio;
u16 throttlequeuedepth;
u8 mask_interrupts;
+ u16 max_chain_frame_sz;
u8 is_imr;
+ bool dev_handle;
};
struct MR_LD_VF_MAP {
u32 size;
@@ -1864,9 +1923,13 @@ struct megasas_instance_template {
#define MEGASAS_IS_LOGICAL(scp) \
(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
-#define MEGASAS_DEV_INDEX(inst, scp) \
- ((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
- scp->device->id
+#define MEGASAS_DEV_INDEX(scp) \
+ (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
+ scp->device->id)
+
+#define MEGASAS_PD_INDEX(scp) \
+ ((scp->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + \
+ scp->device->id)
struct megasas_cmd {
@@ -1877,17 +1940,14 @@ struct megasas_cmd {
u32 index;
u8 sync_cmd;
- u8 cmd_status;
+ u8 cmd_status_drv;
u8 abort_aen;
u8 retry_for_fw_reset;
struct list_head list;
struct scsi_cmnd *scmd;
-
- void *mpt_pthr_cmd_blocked;
- atomic_t mfi_mpt_pthr;
- u8 is_wait_event;
+ u8 flags;
struct megasas_instance *instance;
union {
@@ -1963,14 +2023,17 @@ u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map);
-u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map);
+__le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
-u16 get_updated_dev_handle(struct megasas_instance *instance,
+__le16 get_updated_dev_handle(struct megasas_instance *instance,
struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info);
void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
struct LD_LOAD_BALANCE_INFO *lbInfo);
int megasas_get_ctrl_info(struct megasas_instance *instance);
+/* PD sequence */
+int
+megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend);
int megasas_set_crash_dump_params(struct megasas_instance *instance,
u8 crash_buf_state);
void megasas_free_host_crash_buffer(struct megasas_instance *instance);
@@ -1986,5 +2049,6 @@ void __megasas_return_cmd(struct megasas_instance *instance,
void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
struct megasas_cmd *cmd_mfi, struct megasas_cmd_fusion *cmd_fusion);
int megasas_cmd_type(struct scsi_cmnd *cmd);
+void megasas_setup_jbod_map(struct megasas_instance *instance);
#endif /*LSI_MEGARAID_SAS_H */
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas_base.c b/kernel/drivers/scsi/megaraid/megaraid_sas_base.c
index 890637fdd..97a1c1c33 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -94,8 +94,8 @@ MODULE_PARM_DESC(smp_affinity_enable, "SMP affinity feature enable/disbale Defau
MODULE_LICENSE("GPL");
MODULE_VERSION(MEGASAS_VERSION);
-MODULE_AUTHOR("megaraidlinux@lsi.com");
-MODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
+MODULE_AUTHOR("megaraidlinux.pdl@avagotech.com");
+MODULE_DESCRIPTION("Avago MegaRAID SAS Driver");
int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
static int megasas_get_pd_list(struct megasas_instance *instance);
@@ -135,6 +135,12 @@ static struct pci_device_id megasas_pci_table[] = {
/* Invader */
{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
/* Fury */
+ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER)},
+ /* Intruder */
+ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INTRUDER_24)},
+ /* Intruder 24 port*/
+ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_52)},
+ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)},
{}
};
@@ -215,9 +221,8 @@ struct megasas_cmd *megasas_get_cmd(struct megasas_instance
cmd = list_entry((&instance->cmd_pool)->next,
struct megasas_cmd, list);
list_del_init(&cmd->list);
- atomic_set(&cmd->mfi_mpt_pthr, MFI_MPT_DETACHED);
} else {
- printk(KERN_ERR "megasas: Command pool empty!\n");
+ dev_err(&instance->pdev->dev, "Command pool empty!\n");
}
spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
@@ -225,52 +230,101 @@ struct megasas_cmd *megasas_get_cmd(struct megasas_instance
}
/**
- * __megasas_return_cmd - Return a cmd to free command pool
+ * megasas_return_cmd - Return a cmd to free command pool
* @instance: Adapter soft state
* @cmd: Command packet to be returned to free command pool
*/
inline void
-__megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
+megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
{
- /*
- * Don't go ahead and free the MFI frame, if corresponding
- * MPT frame is not freed(valid for only fusion adapters).
- * In case of MFI adapters, anyways for any allocated MFI
- * frame will have cmd->mfi_mpt_mpthr set to MFI_MPT_DETACHED
+ unsigned long flags;
+ u32 blk_tags;
+ struct megasas_cmd_fusion *cmd_fusion;
+ struct fusion_context *fusion = instance->ctrl_context;
+
+ /* This flag is used only for fusion adapter.
+ * Wait for Interrupt for Polled mode DCMD
*/
- if (atomic_read(&cmd->mfi_mpt_pthr) != MFI_MPT_DETACHED)
+ if (cmd->flags & DRV_DCMD_POLLED_MODE)
return;
+ spin_lock_irqsave(&instance->mfi_pool_lock, flags);
+
+ if (fusion) {
+ blk_tags = instance->max_scsi_cmds + cmd->index;
+ cmd_fusion = fusion->cmd_list[blk_tags];
+ megasas_return_cmd_fusion(instance, cmd_fusion);
+ }
cmd->scmd = NULL;
cmd->frame_count = 0;
- cmd->is_wait_event = 0;
- cmd->mpt_pthr_cmd_blocked = NULL;
-
- if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
- (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
- (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
- (reset_devices))
+ cmd->flags = 0;
+ if (!fusion && reset_devices)
cmd->frame->hdr.cmd = MFI_CMD_INVALID;
-
- atomic_set(&cmd->mfi_mpt_pthr, MFI_LIST_ADDED);
list_add(&cmd->list, (&instance->cmd_pool)->next);
+
+ spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
+
}
-/**
- * megasas_return_cmd - Return a cmd to free command pool
- * @instance: Adapter soft state
- * @cmd: Command packet to be returned to free command pool
- */
-inline void
-megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
+static const char *
+format_timestamp(uint32_t timestamp)
{
- unsigned long flags;
+ static char buffer[32];
- spin_lock_irqsave(&instance->mfi_pool_lock, flags);
- __megasas_return_cmd(instance, cmd);
- spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
+ if ((timestamp & 0xff000000) == 0xff000000)
+ snprintf(buffer, sizeof(buffer), "boot + %us", timestamp &
+ 0x00ffffff);
+ else
+ snprintf(buffer, sizeof(buffer), "%us", timestamp);
+ return buffer;
+}
+
+static const char *
+format_class(int8_t class)
+{
+ static char buffer[6];
+
+ switch (class) {
+ case MFI_EVT_CLASS_DEBUG:
+ return "debug";
+ case MFI_EVT_CLASS_PROGRESS:
+ return "progress";
+ case MFI_EVT_CLASS_INFO:
+ return "info";
+ case MFI_EVT_CLASS_WARNING:
+ return "WARN";
+ case MFI_EVT_CLASS_CRITICAL:
+ return "CRIT";
+ case MFI_EVT_CLASS_FATAL:
+ return "FATAL";
+ case MFI_EVT_CLASS_DEAD:
+ return "DEAD";
+ default:
+ snprintf(buffer, sizeof(buffer), "%d", class);
+ return buffer;
+ }
}
+/**
+ * megasas_decode_evt: Decode FW AEN event and print critical event
+ * for information.
+ * @instance: Adapter soft state
+ */
+static void
+megasas_decode_evt(struct megasas_instance *instance)
+{
+ struct megasas_evt_detail *evt_detail = instance->evt_detail;
+ union megasas_evt_class_locale class_locale;
+ class_locale.word = le32_to_cpu(evt_detail->cl.word);
+
+ if (class_locale.members.class >= MFI_EVT_CLASS_CRITICAL)
+ dev_info(&instance->pdev->dev, "%d (%s/0x%04x/%s) - %s\n",
+ le32_to_cpu(evt_detail->seq_num),
+ format_timestamp(le32_to_cpu(evt_detail->time_stamp)),
+ (class_locale.members.locale),
+ format_class(class_locale.members.class),
+ evt_detail->description);
+}
/**
* The following functions are defined for xscale
@@ -285,6 +339,7 @@ static inline void
megasas_enable_intr_xscale(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
+
regs = instance->reg_set;
writel(0, &(regs)->outbound_intr_mask);
@@ -301,6 +356,7 @@ megasas_disable_intr_xscale(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
u32 mask = 0x1f;
+
regs = instance->reg_set;
writel(mask, &regs->outbound_intr_mask);
/* Dummy readl to force pci flush */
@@ -325,6 +381,7 @@ megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
{
u32 status;
u32 mfiStatus = 0;
+
/*
* Check if it is our interrupt
*/
@@ -360,6 +417,7 @@ megasas_fire_cmd_xscale(struct megasas_instance *instance,
struct megasas_register_set __iomem *regs)
{
unsigned long flags;
+
spin_lock_irqsave(&instance->hba_lock, flags);
writel((frame_phys_addr >> 3)|(frame_count),
&(regs)->inbound_queue_port);
@@ -376,15 +434,16 @@ megasas_adp_reset_xscale(struct megasas_instance *instance,
{
u32 i;
u32 pcidata;
+
writel(MFI_ADP_RESET, &regs->inbound_doorbell);
for (i = 0; i < 3; i++)
msleep(1000); /* sleep for 3 secs */
pcidata = 0;
pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
- printk(KERN_NOTICE "pcidata = %x\n", pcidata);
+ dev_notice(&instance->pdev->dev, "pcidata = %x\n", pcidata);
if (pcidata & 0x2) {
- printk(KERN_NOTICE "mfi 1068 offset read=%x\n", pcidata);
+ dev_notice(&instance->pdev->dev, "mfi 1068 offset read=%x\n", pcidata);
pcidata &= ~0x2;
pci_write_config_dword(instance->pdev,
MFI_1068_PCSR_OFFSET, pcidata);
@@ -395,9 +454,9 @@ megasas_adp_reset_xscale(struct megasas_instance *instance,
pcidata = 0;
pci_read_config_dword(instance->pdev,
MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
- printk(KERN_NOTICE "1068 offset handshake read=%x\n", pcidata);
+ dev_notice(&instance->pdev->dev, "1068 offset handshake read=%x\n", pcidata);
if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
- printk(KERN_NOTICE "1068 offset pcidt=%x\n", pcidata);
+ dev_notice(&instance->pdev->dev, "1068 offset pcidt=%x\n", pcidata);
pcidata = 0;
pci_write_config_dword(instance->pdev,
MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
@@ -414,7 +473,6 @@ static int
megasas_check_reset_xscale(struct megasas_instance *instance,
struct megasas_register_set __iomem *regs)
{
-
if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) &&
(le32_to_cpu(*instance->consumer) ==
MEGASAS_ADPRESET_INPROG_SIGN))
@@ -445,7 +503,7 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
/**
* The following functions are defined for ppc (deviceid : 0x60)
-* controllers
+* controllers
*/
/**
@@ -456,6 +514,7 @@ static inline void
megasas_enable_intr_ppc(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
+
regs = instance->reg_set;
writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
@@ -474,6 +533,7 @@ megasas_disable_intr_ppc(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
u32 mask = 0xFFFFFFFF;
+
regs = instance->reg_set;
writel(mask, &regs->outbound_intr_mask);
/* Dummy readl to force pci flush */
@@ -534,6 +594,7 @@ megasas_fire_cmd_ppc(struct megasas_instance *instance,
struct megasas_register_set __iomem *regs)
{
unsigned long flags;
+
spin_lock_irqsave(&instance->hba_lock, flags);
writel((frame_phys_addr | (frame_count<<1))|1,
&(regs)->inbound_queue_port);
@@ -578,6 +639,7 @@ static inline void
megasas_enable_intr_skinny(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
+
regs = instance->reg_set;
writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
@@ -596,6 +658,7 @@ megasas_disable_intr_skinny(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
u32 mask = 0xFFFFFFFF;
+
regs = instance->reg_set;
writel(mask, &regs->outbound_intr_mask);
/* Dummy readl to force pci flush */
@@ -646,8 +709,8 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
writel(status, &regs->outbound_intr_status);
/*
- * dummy read to flush PCI
- */
+ * dummy read to flush PCI
+ */
readl(&regs->outbound_intr_status);
return mfiStatus;
@@ -666,6 +729,7 @@ megasas_fire_cmd_skinny(struct megasas_instance *instance,
struct megasas_register_set __iomem *regs)
{
unsigned long flags;
+
spin_lock_irqsave(&instance->hba_lock, flags);
writel(upper_32_bits(frame_phys_addr),
&(regs)->inbound_high_queue_port);
@@ -718,6 +782,7 @@ static inline void
megasas_enable_intr_gen2(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
+
regs = instance->reg_set;
writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
@@ -737,6 +802,7 @@ megasas_disable_intr_gen2(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *regs;
u32 mask = 0xFFFFFFFF;
+
regs = instance->reg_set;
writel(mask, &regs->outbound_intr_mask);
/* Dummy readl to force pci flush */
@@ -762,6 +828,7 @@ megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
{
u32 status;
u32 mfiStatus = 0;
+
/*
* Check if it is our interrupt
*/
@@ -798,6 +865,7 @@ megasas_fire_cmd_gen2(struct megasas_instance *instance,
struct megasas_register_set __iomem *regs)
{
unsigned long flags;
+
spin_lock_irqsave(&instance->hba_lock, flags);
writel((frame_phys_addr | (frame_count<<1))|1,
&(regs)->inbound_queue_port);
@@ -812,10 +880,10 @@ static int
megasas_adp_reset_gen2(struct megasas_instance *instance,
struct megasas_register_set __iomem *reg_set)
{
- u32 retry = 0 ;
- u32 HostDiag;
- u32 *seq_offset = &reg_set->seq_offset;
- u32 *hostdiag_offset = &reg_set->host_diag;
+ u32 retry = 0 ;
+ u32 HostDiag;
+ u32 __iomem *seq_offset = &reg_set->seq_offset;
+ u32 __iomem *hostdiag_offset = &reg_set->host_diag;
if (instance->instancet == &megasas_instance_template_skinny) {
seq_offset = &reg_set->fusion_seq_offset;
@@ -833,10 +901,10 @@ megasas_adp_reset_gen2(struct megasas_instance *instance,
HostDiag = (u32)readl(hostdiag_offset);
- while ( !( HostDiag & DIAG_WRITE_ENABLE) ) {
+ while (!(HostDiag & DIAG_WRITE_ENABLE)) {
msleep(100);
HostDiag = (u32)readl(hostdiag_offset);
- printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n",
+ dev_notice(&instance->pdev->dev, "RESETGEN2: retry=%x, hostdiag=%x\n",
retry, HostDiag);
if (retry++ >= 100)
@@ -844,17 +912,17 @@ megasas_adp_reset_gen2(struct megasas_instance *instance,
}
- printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
+ dev_notice(&instance->pdev->dev, "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset);
ssleep(10);
HostDiag = (u32)readl(hostdiag_offset);
- while ( ( HostDiag & DIAG_RESET_ADAPTER) ) {
+ while (HostDiag & DIAG_RESET_ADAPTER) {
msleep(100);
HostDiag = (u32)readl(hostdiag_offset);
- printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n",
+ dev_notice(&instance->pdev->dev, "RESET_GEN2: retry=%x, hostdiag=%x\n",
retry, HostDiag);
if (retry++ >= 1000)
@@ -910,13 +978,12 @@ extern struct megasas_instance_template megasas_instance_template_fusion;
* @instance: Adapter soft state
* @cmd: Command packet to be issued
*
- * For polling, MFI requires the cmd_status to be set to 0xFF before posting.
+ * For polling, MFI requires the cmd_status to be set to MFI_STAT_INVALID_STATUS before posting.
*/
int
megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
{
int seconds;
-
struct megasas_header *frame_hdr = &cmd->frame->hdr;
frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE;
@@ -952,20 +1019,21 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
struct megasas_cmd *cmd, int timeout)
{
int ret = 0;
- cmd->cmd_status = ENODATA;
- cmd->is_wait_event = 1;
+ cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
+
instance->instancet->issue_dcmd(instance, cmd);
if (timeout) {
ret = wait_event_timeout(instance->int_cmd_wait_q,
- cmd->cmd_status != ENODATA, timeout * HZ);
+ cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
if (!ret)
return 1;
} else
wait_event(instance->int_cmd_wait_q,
- cmd->cmd_status != ENODATA);
+ cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS);
- return 0;
+ return (cmd->cmd_status_drv == MFI_STAT_OK) ?
+ 0 : 1;
}
/**
@@ -998,7 +1066,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
* Prepare and issue the abort frame
*/
abort_fr->cmd = MFI_CMD_ABORT;
- abort_fr->cmd_status = 0xFF;
+ abort_fr->cmd_status = MFI_STAT_INVALID_STATUS;
abort_fr->flags = cpu_to_le16(0);
abort_fr->abort_context = cpu_to_le32(cmd_to_abort->index);
abort_fr->abort_mfi_phys_addr_lo =
@@ -1007,13 +1075,13 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr));
cmd->sync_cmd = 1;
- cmd->cmd_status = ENODATA;
+ cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
instance->instancet->issue_dcmd(instance, cmd);
if (timeout) {
ret = wait_event_timeout(instance->abort_cmd_wait_q,
- cmd->cmd_status != ENODATA, timeout * HZ);
+ cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ);
if (!ret) {
dev_err(&instance->pdev->dev, "Command timedout"
"from %s\n", __func__);
@@ -1021,7 +1089,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
}
} else
wait_event(instance->abort_cmd_wait_q,
- cmd->cmd_status != ENODATA);
+ cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS);
cmd->sync_cmd = 0;
@@ -1132,7 +1200,7 @@ static u32 megasas_get_frame_count(struct megasas_instance *instance,
int num_cnt;
int sge_bytes;
u32 sge_sz;
- u32 frame_count=0;
+ u32 frame_count = 0;
sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
sizeof(struct megasas_sge32);
@@ -1163,14 +1231,14 @@ static u32 megasas_get_frame_count(struct megasas_instance *instance,
num_cnt = sge_count - 3;
}
- if(num_cnt>0){
+ if (num_cnt > 0) {
sge_bytes = sge_sz * num_cnt;
frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
}
/* Main frame */
- frame_count +=1;
+ frame_count += 1;
if (frame_count > 7)
frame_count = 8;
@@ -1196,7 +1264,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
struct megasas_pthru_frame *pthru;
is_logical = MEGASAS_IS_LOGICAL(scp);
- device_id = MEGASAS_DEV_INDEX(instance, scp);
+ device_id = MEGASAS_DEV_INDEX(scp);
pthru = (struct megasas_pthru_frame *)cmd->frame;
if (scp->sc_data_direction == PCI_DMA_TODEVICE)
@@ -1227,12 +1295,12 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
/*
- * If the command is for the tape device, set the
- * pthru timeout to the os layer timeout value.
- */
+ * If the command is for the tape device, set the
+ * pthru timeout to the os layer timeout value.
+ */
if (scp->device->type == TYPE_TAPE) {
if ((scp->request->timeout / HZ) > 0xFFFF)
- pthru->timeout = 0xFFFF;
+ pthru->timeout = cpu_to_le16(0xFFFF);
else
pthru->timeout = cpu_to_le16(scp->request->timeout / HZ);
}
@@ -1253,7 +1321,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
&pthru->sgl);
if (pthru->sge_count > instance->max_num_sge) {
- printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
+ dev_err(&instance->pdev->dev, "DCDB too many SGE NUM=%x\n",
pthru->sge_count);
return 0;
}
@@ -1294,7 +1362,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
u16 flags = 0;
struct megasas_io_frame *ldio;
- device_id = MEGASAS_DEV_INDEX(instance, scp);
+ device_id = MEGASAS_DEV_INDEX(scp);
ldio = (struct megasas_io_frame *)cmd->frame;
if (scp->sc_data_direction == PCI_DMA_TODEVICE)
@@ -1394,7 +1462,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
if (ldio->sge_count > instance->max_num_sge) {
- printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
+ dev_err(&instance->pdev->dev, "build_ld_io: sge_count = %x\n",
ldio->sge_count);
return 0;
}
@@ -1447,7 +1515,7 @@ inline int megasas_cmd_type(struct scsi_cmnd *cmd)
/**
* megasas_dump_pending_frames - Dumps the frame address of all pending cmds
- * in FW
+ * in FW
* @instance: Adapter soft state
*/
static inline void
@@ -1461,63 +1529,60 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
u32 sgcount;
u32 max_cmd = instance->max_fw_cmds;
- printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
- printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
+ dev_err(&instance->pdev->dev, "[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
+ dev_err(&instance->pdev->dev, "[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
if (IS_DMA64)
- printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
+ dev_err(&instance->pdev->dev, "[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
else
- printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
+ dev_err(&instance->pdev->dev, "[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
- printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
+ dev_err(&instance->pdev->dev, "[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
for (i = 0; i < max_cmd; i++) {
cmd = instance->cmd_list[i];
- if(!cmd->scmd)
+ if (!cmd->scmd)
continue;
- printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
+ dev_err(&instance->pdev->dev, "[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
if (megasas_cmd_type(cmd->scmd) == READ_WRITE_LDIO) {
ldio = (struct megasas_io_frame *)cmd->frame;
mfi_sgl = &ldio->sgl;
sgcount = ldio->sge_count;
- printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x,"
+ dev_err(&instance->pdev->dev, "[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x,"
" lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
instance->host->host_no, cmd->frame_count, ldio->cmd, ldio->target_id,
le32_to_cpu(ldio->start_lba_lo), le32_to_cpu(ldio->start_lba_hi),
le32_to_cpu(ldio->sense_buf_phys_addr_lo), sgcount);
- }
- else {
+ } else {
pthru = (struct megasas_pthru_frame *) cmd->frame;
mfi_sgl = &pthru->sgl;
sgcount = pthru->sge_count;
- printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, "
+ dev_err(&instance->pdev->dev, "[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, "
"lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
instance->host->host_no, cmd->frame_count, pthru->cmd, pthru->target_id,
pthru->lun, pthru->cdb_len, le32_to_cpu(pthru->data_xfer_len),
le32_to_cpu(pthru->sense_buf_phys_addr_lo), sgcount);
}
- if(megasas_dbg_lvl & MEGASAS_DBG_LVL){
- for (n = 0; n < sgcount; n++){
- if (IS_DMA64)
- printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%llx ",
- le32_to_cpu(mfi_sgl->sge64[n].length),
- le64_to_cpu(mfi_sgl->sge64[n].phys_addr));
- else
- printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",
- le32_to_cpu(mfi_sgl->sge32[n].length),
- le32_to_cpu(mfi_sgl->sge32[n].phys_addr));
+ if (megasas_dbg_lvl & MEGASAS_DBG_LVL) {
+ for (n = 0; n < sgcount; n++) {
+ if (IS_DMA64)
+ dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%llx\n",
+ le32_to_cpu(mfi_sgl->sge64[n].length),
+ le64_to_cpu(mfi_sgl->sge64[n].phys_addr));
+ else
+ dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%x\n",
+ le32_to_cpu(mfi_sgl->sge32[n].length),
+ le32_to_cpu(mfi_sgl->sge32[n].phys_addr));
}
}
- printk(KERN_ERR "\n");
} /*for max_cmd*/
- printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
+ dev_err(&instance->pdev->dev, "[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
for (i = 0; i < max_cmd; i++) {
cmd = instance->cmd_list[i];
- if(cmd->sync_cmd == 1){
- printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
- }
+ if (cmd->sync_cmd == 1)
+ dev_err(&instance->pdev->dev, "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
}
- printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
+ dev_err(&instance->pdev->dev, "[%d]: Dumping Done\n\n",instance->host->host_no);
}
u32
@@ -1635,7 +1700,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
}
if (instance->instancet->build_and_issue_cmd(instance, scmd)) {
- printk(KERN_ERR "megasas: Err returned from build_and_issue_cmd\n");
+ dev_err(&instance->pdev->dev, "Err returned from build_and_issue_cmd\n");
return SCSI_MLQUEUE_HOST_BUSY;
}
@@ -1660,11 +1725,59 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no)
return NULL;
}
+/*
+* megasas_set_dma_alignment - Set DMA alignment for PI enabled VD
+*
+* @sdev: OS provided scsi device
+*
+* Returns void
+*/
+static void megasas_set_dma_alignment(struct scsi_device *sdev)
+{
+ u32 device_id, ld;
+ struct megasas_instance *instance;
+ struct fusion_context *fusion;
+ struct MR_LD_RAID *raid;
+ struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
+
+ instance = megasas_lookup_instance(sdev->host->host_no);
+ fusion = instance->ctrl_context;
+
+ if (!fusion)
+ return;
+
+ if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) {
+ device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL)
+ + sdev->id;
+ local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+ ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
+ raid = MR_LdRaidGet(ld, local_map_ptr);
+
+ if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER)
+ blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
+ }
+}
+
static int megasas_slave_configure(struct scsi_device *sdev)
{
+ u16 pd_index = 0;
+ struct megasas_instance *instance;
+
+ instance = megasas_lookup_instance(sdev->host->host_no);
+ if (instance->allow_fw_scan) {
+ if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+ sdev->type == TYPE_DISK) {
+ pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+ sdev->id;
+ if (instance->pd_list[pd_index].driveState !=
+ MR_PD_STATE_SYSTEM)
+ return -ENXIO;
+ }
+ }
+ megasas_set_dma_alignment(sdev);
/*
- * The RAID firmware may require extended timeouts.
- */
+ * The RAID firmware may require extended timeouts.
+ */
blk_queue_rq_timeout(sdev->request_queue,
MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
@@ -1673,8 +1786,9 @@ static int megasas_slave_configure(struct scsi_device *sdev)
static int megasas_slave_alloc(struct scsi_device *sdev)
{
- u16 pd_index = 0;
+ u16 pd_index = 0;
struct megasas_instance *instance ;
+
instance = megasas_lookup_instance(sdev->host->host_no);
if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
/*
@@ -1683,8 +1797,8 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
pd_index =
(sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
sdev->id;
- if (instance->pd_list[pd_index].driveState ==
- MR_PD_STATE_SYSTEM) {
+ if ((instance->allow_fw_scan || instance->pd_list[pd_index].driveState ==
+ MR_PD_STATE_SYSTEM)) {
return 0;
}
return -ENXIO;
@@ -1698,7 +1812,7 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
* @instance: Adapter soft state
*
*/
-void megasas_complete_outstanding_ioctls(struct megasas_instance *instance)
+static void megasas_complete_outstanding_ioctls(struct megasas_instance *instance)
{
int i;
struct megasas_cmd *cmd_mfi;
@@ -1736,12 +1850,8 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
msleep(1000);
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
- writel(MFI_STOP_ADP,
- &instance->reg_set->doorbell);
+ (instance->ctrl_context)) {
+ writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
/* Flush */
readl(&instance->reg_set->doorbell);
if (instance->mpio && instance->requestorId)
@@ -1795,7 +1905,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
unsigned long flags;
/* If we have already declared adapter dead, donot complete cmds */
- if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR )
+ if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
return;
spin_lock_irqsave(&instance->completion_lock, flags);
@@ -1806,7 +1916,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
while (consumer != producer) {
context = le32_to_cpu(instance->reply_queue[consumer]);
if (context >= instance->max_fw_cmds) {
- printk(KERN_ERR "Unexpected context value %x\n",
+ dev_err(&instance->pdev->dev, "Unexpected context value %x\n",
context);
BUG();
}
@@ -1885,8 +1995,8 @@ static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas: megasas_get_ld_vf_affiliation_111:"
- "Failed to get cmd for scsi%d.\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_vf_affiliation_111:"
+ "Failed to get cmd for scsi%d\n",
instance->host->host_no);
return -ENOMEM;
}
@@ -1894,8 +2004,8 @@ static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
dcmd = &cmd->frame->dcmd;
if (!instance->vf_affiliation_111) {
- printk(KERN_WARNING "megasas: SR-IOV: Couldn't get LD/VF "
- "affiliation for scsi%d.\n", instance->host->host_no);
+ dev_warn(&instance->pdev->dev, "SR-IOV: Couldn't get LD/VF "
+ "affiliation for scsi%d\n", instance->host->host_no);
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
@@ -1909,8 +2019,8 @@ static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
sizeof(struct MR_LD_VF_AFFILIATION_111),
&new_affiliation_111_h);
if (!new_affiliation_111) {
- printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate "
- "memory for new affiliation for scsi%d.\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate "
+ "memory for new affiliation for scsi%d\n",
instance->host->host_no);
megasas_return_cmd(instance, cmd);
return -ENOMEM;
@@ -1922,31 +2032,33 @@ static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
- dcmd->flags = MFI_FRAME_DIR_BOTH;
+ dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
dcmd->timeout = 0;
dcmd->pad_0 = 0;
- dcmd->data_xfer_len = sizeof(struct MR_LD_VF_AFFILIATION_111);
- dcmd->opcode = MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111;
+ dcmd->data_xfer_len =
+ cpu_to_le32(sizeof(struct MR_LD_VF_AFFILIATION_111));
+ dcmd->opcode = cpu_to_le32(MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111);
if (initial)
dcmd->sgl.sge32[0].phys_addr =
- instance->vf_affiliation_111_h;
+ cpu_to_le32(instance->vf_affiliation_111_h);
else
- dcmd->sgl.sge32[0].phys_addr = new_affiliation_111_h;
+ dcmd->sgl.sge32[0].phys_addr =
+ cpu_to_le32(new_affiliation_111_h);
- dcmd->sgl.sge32[0].length =
- sizeof(struct MR_LD_VF_AFFILIATION_111);
+ dcmd->sgl.sge32[0].length = cpu_to_le32(
+ sizeof(struct MR_LD_VF_AFFILIATION_111));
- printk(KERN_WARNING "megasas: SR-IOV: Getting LD/VF affiliation for "
+ dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
"scsi%d\n", instance->host->host_no);
megasas_issue_blocked_cmd(instance, cmd, 0);
if (dcmd->cmd_status) {
- printk(KERN_WARNING "megasas: SR-IOV: LD/VF affiliation DCMD"
- " failed with status 0x%x for scsi%d.\n",
+ dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
+ " failed with status 0x%x for scsi%d\n",
dcmd->cmd_status, instance->host->host_no);
retval = 1; /* Do a scan if we couldn't get affiliation */
goto out;
@@ -1957,9 +2069,8 @@ static int megasas_get_ld_vf_affiliation_111(struct megasas_instance *instance,
for (ld = 0 ; ld < new_affiliation_111->vdCount; ld++)
if (instance->vf_affiliation_111->map[ld].policy[thisVf] !=
new_affiliation_111->map[ld].policy[thisVf]) {
- printk(KERN_WARNING "megasas: SR-IOV: "
- "Got new LD/VF affiliation "
- "for scsi%d.\n",
+ dev_warn(&instance->pdev->dev, "SR-IOV: "
+ "Got new LD/VF affiliation for scsi%d\n",
instance->host->host_no);
memcpy(instance->vf_affiliation_111,
new_affiliation_111,
@@ -1976,11 +2087,7 @@ out:
new_affiliation_111_h);
}
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return retval;
}
@@ -1999,8 +2106,8 @@ static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas: megasas_get_ld_vf_affiliation12: "
- "Failed to get cmd for scsi%d.\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_vf_affiliation12: "
+ "Failed to get cmd for scsi%d\n",
instance->host->host_no);
return -ENOMEM;
}
@@ -2008,8 +2115,8 @@ static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
dcmd = &cmd->frame->dcmd;
if (!instance->vf_affiliation) {
- printk(KERN_WARNING "megasas: SR-IOV: Couldn't get LD/VF "
- "affiliation for scsi%d.\n", instance->host->host_no);
+ dev_warn(&instance->pdev->dev, "SR-IOV: Couldn't get LD/VF "
+ "affiliation for scsi%d\n", instance->host->host_no);
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
@@ -2024,8 +2131,8 @@ static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
sizeof(struct MR_LD_VF_AFFILIATION),
&new_affiliation_h);
if (!new_affiliation) {
- printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate "
- "memory for new affiliation for scsi%d.\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate "
+ "memory for new affiliation for scsi%d\n",
instance->host->host_no);
megasas_return_cmd(instance, cmd);
return -ENOMEM;
@@ -2037,31 +2144,33 @@ static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
- dcmd->flags = MFI_FRAME_DIR_BOTH;
+ dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
dcmd->timeout = 0;
dcmd->pad_0 = 0;
- dcmd->data_xfer_len = (MAX_LOGICAL_DRIVES + 1) *
- sizeof(struct MR_LD_VF_AFFILIATION);
- dcmd->opcode = MR_DCMD_LD_VF_MAP_GET_ALL_LDS;
+ dcmd->data_xfer_len = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
+ sizeof(struct MR_LD_VF_AFFILIATION));
+ dcmd->opcode = cpu_to_le32(MR_DCMD_LD_VF_MAP_GET_ALL_LDS);
if (initial)
- dcmd->sgl.sge32[0].phys_addr = instance->vf_affiliation_h;
+ dcmd->sgl.sge32[0].phys_addr =
+ cpu_to_le32(instance->vf_affiliation_h);
else
- dcmd->sgl.sge32[0].phys_addr = new_affiliation_h;
+ dcmd->sgl.sge32[0].phys_addr =
+ cpu_to_le32(new_affiliation_h);
- dcmd->sgl.sge32[0].length = (MAX_LOGICAL_DRIVES + 1) *
- sizeof(struct MR_LD_VF_AFFILIATION);
+ dcmd->sgl.sge32[0].length = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
+ sizeof(struct MR_LD_VF_AFFILIATION));
- printk(KERN_WARNING "megasas: SR-IOV: Getting LD/VF affiliation for "
+ dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
"scsi%d\n", instance->host->host_no);
megasas_issue_blocked_cmd(instance, cmd, 0);
if (dcmd->cmd_status) {
- printk(KERN_WARNING "megasas: SR-IOV: LD/VF affiliation DCMD"
- " failed with status 0x%x for scsi%d.\n",
+ dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
+ " failed with status 0x%x for scsi%d\n",
dcmd->cmd_status, instance->host->host_no);
retval = 1; /* Do a scan if we couldn't get affiliation */
goto out;
@@ -2069,8 +2178,8 @@ static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
if (!initial) {
if (!new_affiliation->ldCount) {
- printk(KERN_WARNING "megasas: SR-IOV: Got new LD/VF "
- "affiliation for passive path for scsi%d.\n",
+ dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
+ "affiliation for passive path for scsi%d\n",
instance->host->host_no);
retval = 1;
goto out;
@@ -2135,8 +2244,8 @@ static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
}
out:
if (doscan) {
- printk(KERN_WARNING "megasas: SR-IOV: Got new LD/VF "
- "affiliation for scsi%d.\n", instance->host->host_no);
+ dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
+ "affiliation for scsi%d\n", instance->host->host_no);
memcpy(instance->vf_affiliation, new_affiliation,
new_affiliation->size);
retval = 1;
@@ -2147,11 +2256,7 @@ out:
(MAX_LOGICAL_DRIVES + 1) *
sizeof(struct MR_LD_VF_AFFILIATION),
new_affiliation, new_affiliation_h);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return retval;
}
@@ -2180,8 +2285,8 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas: megasas_sriov_start_heartbeat: "
- "Failed to get cmd for scsi%d.\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_sriov_start_heartbeat: "
+ "Failed to get cmd for scsi%d\n",
instance->host->host_no);
return -ENOMEM;
}
@@ -2194,9 +2299,9 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
sizeof(struct MR_CTRL_HB_HOST_MEM),
&instance->hb_host_mem_h);
if (!instance->hb_host_mem) {
- printk(KERN_DEBUG "megasas: SR-IOV: Couldn't allocate"
- " memory for heartbeat host memory for "
- "scsi%d.\n", instance->host->host_no);
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate"
+ " memory for heartbeat host memory for scsi%d\n",
+ instance->host->host_no);
retval = -ENOMEM;
goto out;
}
@@ -2204,39 +2309,33 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
- dcmd->mbox.s[0] = sizeof(struct MR_CTRL_HB_HOST_MEM);
+ dcmd->mbox.s[0] = cpu_to_le16(sizeof(struct MR_CTRL_HB_HOST_MEM));
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
- dcmd->flags = MFI_FRAME_DIR_BOTH;
+ dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
dcmd->timeout = 0;
dcmd->pad_0 = 0;
- dcmd->data_xfer_len = sizeof(struct MR_CTRL_HB_HOST_MEM);
- dcmd->opcode = MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC;
- dcmd->sgl.sge32[0].phys_addr = instance->hb_host_mem_h;
- dcmd->sgl.sge32[0].length = sizeof(struct MR_CTRL_HB_HOST_MEM);
+ dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM));
+ dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC);
+ dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->hb_host_mem_h);
+ dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM));
- printk(KERN_WARNING "megasas: SR-IOV: Starting heartbeat for scsi%d\n",
+ dev_warn(&instance->pdev->dev, "SR-IOV: Starting heartbeat for scsi%d\n",
instance->host->host_no);
- if (!megasas_issue_polled(instance, cmd)) {
- retval = 0;
- } else {
- printk(KERN_WARNING "megasas: SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
- "_MEM_ALLOC DCMD timed out for scsi%d\n",
- instance->host->host_no);
- retval = 1;
- goto out;
- }
-
+ if (instance->ctrl_context && !instance->mask_interrupts)
+ retval = megasas_issue_blocked_cmd(instance, cmd,
+ MEGASAS_ROUTINE_WAIT_TIME_VF);
+ else
+ retval = megasas_issue_polled(instance, cmd);
- if (dcmd->cmd_status) {
- printk(KERN_WARNING "megasas: SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
- "_MEM_ALLOC DCMD failed with status 0x%x for scsi%d\n",
- dcmd->cmd_status,
- instance->host->host_no);
+ if (retval) {
+ dev_warn(&instance->pdev->dev, "SR-IOV: MR_DCMD_CTRL_SHARED_HOST"
+ "_MEM_ALLOC DCMD %s for scsi%d\n",
+ (dcmd->cmd_status == MFI_STAT_INVALID_STATUS) ?
+ "timed out" : "failed", instance->host->host_no);
retval = 1;
- goto out;
}
out:
@@ -2258,7 +2357,7 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr)
mod_timer(&instance->sriov_heartbeat_timer,
jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
} else {
- printk(KERN_WARNING "megasas: SR-IOV: Heartbeat never "
+ dev_warn(&instance->pdev->dev, "SR-IOV: Heartbeat never "
"completed for scsi%d\n", instance->host->host_no);
schedule_work(&instance->work_init);
}
@@ -2296,7 +2395,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
&clist_local);
spin_unlock_irqrestore(&instance->hba_lock, flags);
- printk(KERN_NOTICE "megasas: HBA reset wait ...\n");
+ dev_notice(&instance->pdev->dev, "HBA reset wait ...\n");
for (i = 0; i < wait_time; i++) {
msleep(1000);
spin_lock_irqsave(&instance->hba_lock, flags);
@@ -2307,37 +2406,37 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
}
if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
- printk(KERN_NOTICE "megasas: reset: Stopping HBA.\n");
+ dev_notice(&instance->pdev->dev, "reset: Stopping HBA.\n");
spin_lock_irqsave(&instance->hba_lock, flags);
- instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
+ instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
spin_unlock_irqrestore(&instance->hba_lock, flags);
return FAILED;
}
- reset_index = 0;
+ reset_index = 0;
while (!list_empty(&clist_local)) {
- reset_cmd = list_entry((&clist_local)->next,
+ reset_cmd = list_entry((&clist_local)->next,
struct megasas_cmd, list);
list_del_init(&reset_cmd->list);
if (reset_cmd->scmd) {
reset_cmd->scmd->result = DID_RESET << 16;
- printk(KERN_NOTICE "%d:%p reset [%02x]\n",
+ dev_notice(&instance->pdev->dev, "%d:%p reset [%02x]\n",
reset_index, reset_cmd,
reset_cmd->scmd->cmnd[0]);
reset_cmd->scmd->scsi_done(reset_cmd->scmd);
megasas_return_cmd(instance, reset_cmd);
} else if (reset_cmd->sync_cmd) {
- printk(KERN_NOTICE "megasas:%p synch cmds"
+ dev_notice(&instance->pdev->dev, "%p synch cmds"
"reset queue\n",
reset_cmd);
- reset_cmd->cmd_status = ENODATA;
+ reset_cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
instance->instancet->fire_cmd(instance,
reset_cmd->frame_phys_addr,
0, instance->reg_set);
} else {
- printk(KERN_NOTICE "megasas: %p unexpected"
+ dev_notice(&instance->pdev->dev, "%p unexpected"
"cmds lst\n",
reset_cmd);
}
@@ -2348,14 +2447,13 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
}
for (i = 0; i < resetwaittime; i++) {
-
int outstanding = atomic_read(&instance->fw_outstanding);
if (!outstanding)
break;
if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
- printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
+ dev_notice(&instance->pdev->dev, "[%2d]waiting for %d "
"commands to complete\n",i,outstanding);
/*
* Call cmd completion routine. Cmd to be
@@ -2387,10 +2485,8 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
i++;
} while (i <= 3);
- if (atomic_read(&instance->fw_outstanding) &&
- !kill_adapter_flag) {
+ if (atomic_read(&instance->fw_outstanding) && !kill_adapter_flag) {
if (instance->disableOnlineCtrlReset == 0) {
-
megasas_do_ocr(instance);
/* wait for 5 secs to let FW finish the pending cmds */
@@ -2406,11 +2502,11 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
if (atomic_read(&instance->fw_outstanding) ||
(kill_adapter_flag == 2)) {
- printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
+ dev_notice(&instance->pdev->dev, "pending cmds after reset\n");
/*
- * Send signal to FW to stop processing any pending cmds.
- * The controller will be taken offline by the OS now.
- */
+ * Send signal to FW to stop processing any pending cmds.
+ * The controller will be taken offline by the OS now.
+ */
if ((instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
@@ -2423,12 +2519,12 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
}
megasas_dump_pending_frames(instance);
spin_lock_irqsave(&instance->hba_lock, flags);
- instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
+ instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
spin_unlock_irqrestore(&instance->hba_lock, flags);
return FAILED;
}
- printk(KERN_NOTICE "megaraid_sas: no pending cmds after reset\n");
+ dev_notice(&instance->pdev->dev, "no pending cmds after reset\n");
return SUCCESS;
}
@@ -2452,16 +2548,15 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
scmd->cmnd[0], scmd->retries);
if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
- printk(KERN_ERR "megasas: cannot recover from previous reset "
- "failures\n");
+ dev_err(&instance->pdev->dev, "cannot recover from previous reset failures\n");
return FAILED;
}
ret_val = megasas_wait_for_outstanding(instance);
if (ret_val == SUCCESS)
- printk(KERN_NOTICE "megasas: reset successful \n");
+ dev_notice(&instance->pdev->dev, "reset successful\n");
else
- printk(KERN_ERR "megasas: failed to do reset\n");
+ dev_err(&instance->pdev->dev, "failed to do reset\n");
return ret_val;
}
@@ -2503,14 +2598,10 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
*/
static int megasas_reset_device(struct scsi_cmnd *scmd)
{
- int ret;
-
/*
* First wait for all commands to complete
*/
- ret = megasas_generic_reset(scmd);
-
- return ret;
+ return megasas_generic_reset(scmd);
}
/**
@@ -2520,15 +2611,13 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
{
int ret;
struct megasas_instance *instance;
+
instance = (struct megasas_instance *)scmd->device->host->hostdata;
/*
* First wait for all commands to complete
*/
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+ if (instance->ctrl_context)
ret = megasas_reset_fusion(scmd->device->host, 1);
else
ret = megasas_generic_reset(scmd);
@@ -2538,7 +2627,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
/**
* megasas_bios_param - Returns disk geometry for a disk
- * @sdev: device handle
+ * @sdev: device handle
* @bdev: block device
* @capacity: drive capacity
* @geom: geometry parameters
@@ -2551,6 +2640,7 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
int sectors;
sector_t cylinders;
unsigned long tmp;
+
/* Default heads (64) & sectors (32) */
heads = 64;
sectors = 32;
@@ -2597,6 +2687,7 @@ static void
megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
{
unsigned long flags;
+
/*
* Don't signal app if it is just an aborted previously registered aen
*/
@@ -2612,18 +2703,15 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
instance->aen_cmd = NULL;
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
if ((instance->unload == 0) &&
((instance->issuepend_done == 1))) {
struct megasas_aen_event *ev;
+
ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev) {
- printk(KERN_ERR "megasas_service_aen: out of memory\n");
+ dev_err(&instance->pdev->dev, "megasas_service_aen: out of memory\n");
} else {
ev->instance = instance;
instance->ev = ev;
@@ -2680,8 +2768,7 @@ megasas_fw_crash_buffer_show(struct device *cdev,
buff_addr = (unsigned long) buf;
- if (buff_offset >
- (instance->fw_crash_buffer_size * dmachunk)) {
+ if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) {
dev_err(&instance->pdev->dev,
"Firmware crash dump offset is out of range\n");
spin_unlock_irqrestore(&instance->crashdump_lock, flags);
@@ -2693,7 +2780,7 @@ megasas_fw_crash_buffer_show(struct device *cdev,
src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] +
(buff_offset % dmachunk);
- memcpy(buf, (void *)src_addr, size);
+ memcpy(buf, (void *)src_addr, size);
spin_unlock_irqrestore(&instance->crashdump_lock, flags);
return size;
@@ -2753,6 +2840,7 @@ megasas_fw_crash_state_show(struct device *cdev,
struct Scsi_Host *shost = class_to_shost(cdev);
struct megasas_instance *instance =
(struct megasas_instance *) shost->hostdata;
+
return snprintf(buf, PAGE_SIZE, "%d\n", instance->fw_crash_state);
}
@@ -2786,7 +2874,7 @@ struct device_attribute *megaraid_host_attrs[] = {
static struct scsi_host_template megasas_template = {
.module = THIS_MODULE,
- .name = "LSI SAS based MegaRAID driver",
+ .name = "Avago SAS based MegaRAID driver",
.proc_name = "megaraid_sas",
.slave_configure = megasas_slave_configure,
.slave_alloc = megasas_slave_alloc,
@@ -2815,11 +2903,7 @@ static void
megasas_complete_int_cmd(struct megasas_instance *instance,
struct megasas_cmd *cmd)
{
- cmd->cmd_status = cmd->frame->io.cmd_status;
-
- if (cmd->cmd_status == ENODATA) {
- cmd->cmd_status = 0;
- }
+ cmd->cmd_status_drv = cmd->frame->io.cmd_status;
wake_up(&instance->int_cmd_wait_q);
}
@@ -2838,11 +2922,9 @@ megasas_complete_abort(struct megasas_instance *instance,
{
if (cmd->sync_cmd) {
cmd->sync_cmd = 0;
- cmd->cmd_status = 0;
+ cmd->cmd_status_drv = 0;
wake_up(&instance->abort_cmd_wait_q);
}
-
- return;
}
/**
@@ -2850,10 +2932,10 @@ megasas_complete_abort(struct megasas_instance *instance,
* @instance: Adapter soft state
* @cmd: Command to be completed
* @alt_status: If non-zero, use this value as status to
- * SCSI mid-layer instead of the value returned
- * by the FW. This should be used if caller wants
- * an alternate status (as in the case of aborted
- * commands)
+ * SCSI mid-layer instead of the value returned
+ * by the FW. This should be used if caller wants
+ * an alternate status (as in the case of aborted
+ * commands)
*/
void
megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
@@ -2863,7 +2945,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
struct megasas_header *hdr = &cmd->frame->hdr;
unsigned long flags;
struct fusion_context *fusion = instance->ctrl_context;
- u32 opcode;
+ u32 opcode, status;
/* flag for the retry reset */
cmd->retry_for_fw_reset = 0;
@@ -2877,10 +2959,10 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
MR_DCMD_CTRL_EVENT_GET_INFO left over from the main kernel
when booting the kdump kernel. Ignore this command to
prevent a kernel panic on shutdown of the kdump kernel. */
- printk(KERN_WARNING "megaraid_sas: MFI_CMD_INVALID command "
- "completed.\n");
- printk(KERN_WARNING "megaraid_sas: If you have a controller "
- "other than PERC5, please upgrade your firmware.\n");
+ dev_warn(&instance->pdev->dev, "MFI_CMD_INVALID command "
+ "completed\n");
+ dev_warn(&instance->pdev->dev, "If you have a controller "
+ "other than PERC5, please upgrade your firmware\n");
break;
case MFI_CMD_PD_SCSI_IO:
case MFI_CMD_LD_SCSI_IO:
@@ -2948,7 +3030,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
break;
default:
- printk(KERN_DEBUG "megasas: MFI FW status %#x\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "MFI FW status %#x\n",
hdr->cmd_status);
cmd->scmd->result = DID_ERROR << 16;
break;
@@ -2971,15 +3053,14 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
&& (cmd->frame->dcmd.mbox.b[1] == 1)) {
fusion->fast_path_io = 0;
spin_lock_irqsave(instance->host->host_lock, flags);
+ instance->map_update_cmd = NULL;
if (cmd->frame->hdr.cmd_status != 0) {
if (cmd->frame->hdr.cmd_status !=
MFI_STAT_NOT_FOUND)
- printk(KERN_WARNING "megasas: map sync"
- "failed, status = 0x%x.\n",
+ dev_warn(&instance->pdev->dev, "map syncfailed, status = 0x%x\n",
cmd->frame->hdr.cmd_status);
else {
- megasas_return_mfi_mpt_pthr(instance,
- cmd, cmd->mpt_pthr_cmd_blocked);
+ megasas_return_cmd(instance, cmd);
spin_unlock_irqrestore(
instance->host->host_lock,
flags);
@@ -2987,8 +3068,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
}
} else
instance->map_id++;
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
+ megasas_return_cmd(instance, cmd);
/*
* Set fast path IO to ZERO.
@@ -3011,6 +3091,27 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
spin_unlock_irqrestore(&poll_aen_lock, flags);
}
+ /* FW has an updated PD sequence */
+ if ((opcode == MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
+ (cmd->frame->dcmd.mbox.b[0] == 1)) {
+
+ spin_lock_irqsave(instance->host->host_lock, flags);
+ status = cmd->frame->hdr.cmd_status;
+ instance->jbod_seq_cmd = NULL;
+ megasas_return_cmd(instance, cmd);
+
+ if (status == MFI_STAT_OK) {
+ instance->pd_seq_map_id++;
+ /* Re-register a pd sync seq num cmd */
+ if (megasas_sync_pd_seq_num(instance, true))
+ instance->use_seqnum_jbod_fp = false;
+ } else
+ instance->use_seqnum_jbod_fp = false;
+
+ spin_unlock_irqrestore(instance->host->host_lock, flags);
+ break;
+ }
+
/*
* See if got an event notification
*/
@@ -3029,7 +3130,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
break;
default:
- printk("megasas: Unknown command completed! [0x%X]\n",
+ dev_info(&instance->pdev->dev, "Unknown command completed! [0x%X]\n",
hdr->cmd);
break;
}
@@ -3037,7 +3138,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
/**
* megasas_issue_pending_cmds_again - issue all pending cmds
- * in FW again because of the fw reset
+ * in FW again because of the fw reset
* @instance: Adapter soft state
*/
static inline void
@@ -3055,19 +3156,19 @@ megasas_issue_pending_cmds_again(struct megasas_instance *instance)
spin_unlock_irqrestore(&instance->hba_lock, flags);
while (!list_empty(&clist_local)) {
- cmd = list_entry((&clist_local)->next,
+ cmd = list_entry((&clist_local)->next,
struct megasas_cmd, list);
list_del_init(&cmd->list);
if (cmd->sync_cmd || cmd->scmd) {
- printk(KERN_NOTICE "megaraid_sas: command %p, %p:%d"
- "detected to be pending while HBA reset.\n",
+ dev_notice(&instance->pdev->dev, "command %p, %p:%d"
+ "detected to be pending while HBA reset\n",
cmd, cmd->scmd, cmd->sync_cmd);
cmd->retry_for_fw_reset++;
if (cmd->retry_for_fw_reset == 3) {
- printk(KERN_NOTICE "megaraid_sas: cmd %p, %p:%d"
+ dev_notice(&instance->pdev->dev, "cmd %p, %p:%d"
"was tried multiple times during reset."
"Shutting down the HBA\n",
cmd, cmd->scmd, cmd->sync_cmd);
@@ -3080,18 +3181,18 @@ megasas_issue_pending_cmds_again(struct megasas_instance *instance)
if (cmd->sync_cmd == 1) {
if (cmd->scmd) {
- printk(KERN_NOTICE "megaraid_sas: unexpected"
+ dev_notice(&instance->pdev->dev, "unexpected"
"cmd attached to internal command!\n");
}
- printk(KERN_NOTICE "megasas: %p synchronous cmd"
+ dev_notice(&instance->pdev->dev, "%p synchronous cmd"
"on the internal reset queue,"
"issue it again.\n", cmd);
- cmd->cmd_status = ENODATA;
+ cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS;
instance->instancet->fire_cmd(instance,
- cmd->frame_phys_addr ,
+ cmd->frame_phys_addr,
0, instance->reg_set);
} else if (cmd->scmd) {
- printk(KERN_NOTICE "megasas: %p scsi cmd [%02x]"
+ dev_notice(&instance->pdev->dev, "%p scsi cmd [%02x]"
"detected on the internal queue, issue again.\n",
cmd, cmd->scmd->cmnd[0]);
@@ -3100,22 +3201,22 @@ megasas_issue_pending_cmds_again(struct megasas_instance *instance)
cmd->frame_phys_addr,
cmd->frame_count-1, instance->reg_set);
} else {
- printk(KERN_NOTICE "megasas: %p unexpected cmd on the"
+ dev_notice(&instance->pdev->dev, "%p unexpected cmd on the"
"internal reset defer list while re-issue!!\n",
cmd);
}
}
if (instance->aen_cmd) {
- printk(KERN_NOTICE "megaraid_sas: aen_cmd in def process\n");
+ dev_notice(&instance->pdev->dev, "aen_cmd in def process\n");
megasas_return_cmd(instance, instance->aen_cmd);
- instance->aen_cmd = NULL;
+ instance->aen_cmd = NULL;
}
/*
- * Initiate AEN (Asynchronous Event Notification)
- */
+ * Initiate AEN (Asynchronous Event Notification)
+ */
seq_num = instance->last_seq_num;
class_locale.members.reserved = 0;
class_locale.members.locale = MR_EVT_LOCALE_ALL;
@@ -3142,17 +3243,17 @@ megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
u32 defer_index;
unsigned long flags;
- defer_index = 0;
+ defer_index = 0;
spin_lock_irqsave(&instance->mfi_pool_lock, flags);
for (i = 0; i < max_cmd; i++) {
cmd = instance->cmd_list[i];
if (cmd->sync_cmd == 1 || cmd->scmd) {
- printk(KERN_NOTICE "megasas: moving cmd[%d]:%p:%d:%p"
+ dev_notice(&instance->pdev->dev, "moving cmd[%d]:%p:%d:%p"
"on the defer queue as internal\n",
defer_index, cmd, cmd->sync_cmd, cmd->scmd);
if (!list_empty(&cmd->list)) {
- printk(KERN_NOTICE "megaraid_sas: ERROR while"
+ dev_notice(&instance->pdev->dev, "ERROR while"
" moving this cmd:%p, %d %p, it was"
"discovered on some list?\n",
cmd, cmd->sync_cmd, cmd->scmd);
@@ -3177,13 +3278,13 @@ process_fw_state_change_wq(struct work_struct *work)
unsigned long flags;
if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
- printk(KERN_NOTICE "megaraid_sas: error, recovery st %x \n",
+ dev_notice(&instance->pdev->dev, "error, recovery st %x\n",
instance->adprecovery);
return ;
}
if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
- printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
+ dev_notice(&instance->pdev->dev, "FW detected to be in fault"
"state, restarting it...\n");
instance->instancet->disable_intr(instance);
@@ -3191,21 +3292,21 @@ process_fw_state_change_wq(struct work_struct *work)
atomic_set(&instance->fw_reset_no_pci_access, 1);
instance->instancet->adp_reset(instance, instance->reg_set);
- atomic_set(&instance->fw_reset_no_pci_access, 0 );
+ atomic_set(&instance->fw_reset_no_pci_access, 0);
- printk(KERN_NOTICE "megaraid_sas: FW restarted successfully,"
+ dev_notice(&instance->pdev->dev, "FW restarted successfully,"
"initiating next stage...\n");
- printk(KERN_NOTICE "megaraid_sas: HBA recovery state machine,"
+ dev_notice(&instance->pdev->dev, "HBA recovery state machine,"
"state 2 starting...\n");
- /*waitting for about 20 second before start the second init*/
+ /* waiting for about 20 second before start the second init */
for (wait = 0; wait < 30; wait++) {
msleep(1000);
}
if (megasas_transition_to_ready(instance, 1)) {
- printk(KERN_NOTICE "megaraid_sas:adapter not ready\n");
+ dev_notice(&instance->pdev->dev, "adapter not ready\n");
atomic_set(&instance->fw_reset_no_pci_access, 1);
megaraid_sas_kill_hba(instance);
@@ -3232,15 +3333,14 @@ process_fw_state_change_wq(struct work_struct *work)
megasas_issue_pending_cmds_again(instance);
instance->issuepend_done = 1;
}
- return ;
}
/**
* megasas_deplete_reply_queue - Processes all completed commands
* @instance: Adapter soft state
* @alt_status: Alternate status to be returned to
- * SCSI mid-layer instead of the status
- * returned by the FW
+ * SCSI mid-layer instead of the status
+ * returned by the FW
* Note: this must be called with hba lock held
*/
static int
@@ -3270,13 +3370,13 @@ megasas_deplete_reply_queue(struct megasas_instance *instance,
instance->reg_set) & MFI_STATE_MASK;
if (fw_state != MFI_STATE_FAULT) {
- printk(KERN_NOTICE "megaraid_sas: fw state:%x\n",
+ dev_notice(&instance->pdev->dev, "fw state:%x\n",
fw_state);
}
if ((fw_state == MFI_STATE_FAULT) &&
(instance->disableOnlineCtrlReset == 0)) {
- printk(KERN_NOTICE "megaraid_sas: wait adp restart\n");
+ dev_notice(&instance->pdev->dev, "wait adp restart\n");
if ((instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS1064R) ||
@@ -3297,14 +3397,14 @@ megasas_deplete_reply_queue(struct megasas_instance *instance,
atomic_set(&instance->fw_outstanding, 0);
megasas_internal_reset_defer_cmds(instance);
- printk(KERN_NOTICE "megasas: fwState=%x, stage:%d\n",
+ dev_notice(&instance->pdev->dev, "fwState=%x, stage:%d\n",
fw_state, instance->adprecovery);
schedule_work(&instance->work_init);
return IRQ_HANDLED;
} else {
- printk(KERN_NOTICE "megasas: fwstate:%x, dis_OCR=%x\n",
+ dev_notice(&instance->pdev->dev, "fwstate:%x, dis_OCR=%x\n",
fw_state, instance->disableOnlineCtrlReset);
}
}
@@ -3320,13 +3420,13 @@ static irqreturn_t megasas_isr(int irq, void *devp)
struct megasas_irq_context *irq_context = devp;
struct megasas_instance *instance = irq_context->instance;
unsigned long flags;
- irqreturn_t rc;
+ irqreturn_t rc;
if (atomic_read(&instance->fw_reset_no_pci_access))
return IRQ_HANDLED;
spin_lock_irqsave(&instance->hba_lock, flags);
- rc = megasas_deplete_reply_queue(instance, DID_OK);
+ rc = megasas_deplete_reply_queue(instance, DID_OK);
spin_unlock_irqrestore(&instance->hba_lock, flags);
return rc;
@@ -3354,7 +3454,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
fw_state = abs_state & MFI_STATE_MASK;
if (fw_state != MFI_STATE_READY)
- printk(KERN_INFO "megasas: Waiting for FW to come to ready"
+ dev_info(&instance->pdev->dev, "Waiting for FW to come to ready"
" state\n");
while (fw_state != MFI_STATE_READY) {
@@ -3362,7 +3462,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
switch (fw_state) {
case MFI_STATE_FAULT:
- printk(KERN_DEBUG "megasas: FW in FAULT state!!\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW in FAULT state!!\n");
if (ocr) {
max_wait = MEGASAS_RESET_WAIT_TIME;
cur_state = MFI_STATE_FAULT;
@@ -3378,22 +3478,14 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FURY)) {
+ (instance->ctrl_context))
writel(
MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
&instance->reg_set->doorbell);
- } else {
+ else
writel(
MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
&instance->reg_set->inbound_doorbell);
- }
max_wait = MEGASAS_RESET_WAIT_TIME;
cur_state = MFI_STATE_WAIT_HANDSHAKE;
@@ -3404,17 +3496,10 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FURY)) {
+ (instance->ctrl_context))
writel(MFI_INIT_HOTPLUG,
&instance->reg_set->doorbell);
- } else
+ else
writel(MFI_INIT_HOTPLUG,
&instance->reg_set->inbound_doorbell);
@@ -3431,24 +3516,11 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
(instance->pdev->device ==
PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
- (instance->pdev->device
- == PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device
- == PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device
- == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device
- == PCI_DEVICE_ID_LSI_FURY)) {
+ (instance->ctrl_context)) {
writel(MFI_RESET_FLAGS,
&instance->reg_set->doorbell);
- if ((instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FURY)) {
+
+ if (instance->ctrl_context) {
for (i = 0; i < (10 * 1000); i += 20) {
if (readl(
&instance->
@@ -3501,7 +3573,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
break;
default:
- printk(KERN_DEBUG "megasas: Unknown state 0x%x\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Unknown state 0x%x\n",
fw_state);
return -ENODEV;
}
@@ -3523,7 +3595,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
* Return error if fw_state hasn't changed after max_wait
*/
if (curr_abs_state == abs_state) {
- printk(KERN_DEBUG "FW state [%d] hasn't changed "
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "FW state [%d] hasn't changed "
"in %d secs\n", fw_state, max_wait);
return -ENODEV;
}
@@ -3531,7 +3603,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
abs_state = curr_abs_state;
fw_state = curr_abs_state & MFI_STATE_MASK;
}
- printk(KERN_INFO "megasas: FW now in Ready state\n");
+ dev_info(&instance->pdev->dev, "FW now in Ready state\n");
return 0;
}
@@ -3602,9 +3674,8 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
sizeof(struct megasas_sge32);
- if (instance->flag_ieee) {
+ if (instance->flag_ieee)
sge_sz = sizeof(struct megasas_sge_skinny);
- }
/*
* For MFI controllers.
@@ -3626,7 +3697,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
instance->pdev, total_sz, 256, 0);
if (!instance->frame_dma_pool) {
- printk(KERN_DEBUG "megasas: failed to setup frame pool\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup frame pool\n");
return -ENOMEM;
}
@@ -3634,7 +3705,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
instance->pdev, 128, 4, 0);
if (!instance->sense_dma_pool) {
- printk(KERN_DEBUG "megasas: failed to setup sense pool\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup sense pool\n");
pci_pool_destroy(instance->frame_dma_pool);
instance->frame_dma_pool = NULL;
@@ -3662,7 +3733,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
* whatever has been allocated
*/
if (!cmd->frame || !cmd->sense) {
- printk(KERN_DEBUG "megasas: pci_pool_alloc failed \n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "pci_pool_alloc failed\n");
megasas_teardown_frame_pool(instance);
return -ENOMEM;
}
@@ -3670,11 +3741,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
memset(cmd->frame, 0, total_sz);
cmd->frame->io.context = cpu_to_le32(cmd->index);
cmd->frame->io.pad_0 = 0;
- if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
- (instance->pdev->device != PCI_DEVICE_ID_LSI_PLASMA) &&
- (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
- (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
- (reset_devices))
+ if (!instance->ctrl_context && reset_devices)
cmd->frame->hdr.cmd = MFI_CMD_INVALID;
}
@@ -3688,6 +3755,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
void megasas_free_cmds(struct megasas_instance *instance)
{
int i;
+
/* First free the MFI frame pool */
megasas_teardown_frame_pool(instance);
@@ -3740,7 +3808,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance)
instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
if (!instance->cmd_list) {
- printk(KERN_DEBUG "megasas: out of memory\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "out of memory\n");
return -ENOMEM;
}
@@ -3766,7 +3834,6 @@ int megasas_alloc_cmds(struct megasas_instance *instance)
cmd = instance->cmd_list[i];
memset(cmd, 0, sizeof(struct megasas_cmd));
cmd->index = i;
- atomic_set(&cmd->mfi_mpt_pthr, MFI_LIST_ADDED);
cmd->scmd = NULL;
cmd->instance = instance;
@@ -3777,7 +3844,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance)
* Create a frame pool and assign one frame to each cmd
*/
if (megasas_create_frame_pool(instance)) {
- printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error creating frame DMA pool\n");
megasas_free_cmds(instance);
}
@@ -3806,7 +3873,7 @@ megasas_get_pd_list(struct megasas_instance *instance)
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "(get_pd_list): Failed to get cmd\n");
return -ENOMEM;
}
@@ -3816,7 +3883,7 @@ megasas_get_pd_list(struct megasas_instance *instance)
MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
if (!ci) {
- printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc mem for pd_list\n");
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
@@ -3827,7 +3894,7 @@ megasas_get_pd_list(struct megasas_instance *instance)
dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
dcmd->mbox.b[1] = 0;
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
dcmd->timeout = 0;
@@ -3844,12 +3911,12 @@ megasas_get_pd_list(struct megasas_instance *instance)
ret = megasas_issue_polled(instance, cmd);
/*
- * the following function will get the instance PD LIST.
- */
+ * the following function will get the instance PD LIST.
+ */
pd_addr = ci->addr;
- if ( ret == 0 &&
+ if (ret == 0 &&
(le32_to_cpu(ci->count) <
(MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
@@ -3874,11 +3941,7 @@ megasas_get_pd_list(struct megasas_instance *instance)
MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
ci, ci_h);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return ret;
}
@@ -3905,7 +3968,7 @@ megasas_get_ld_list(struct megasas_instance *instance)
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_list: Failed to get cmd\n");
return -ENOMEM;
}
@@ -3916,7 +3979,7 @@ megasas_get_ld_list(struct megasas_instance *instance)
&ci_h);
if (!ci) {
- printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc mem in get_ld_list\n");
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
@@ -3927,7 +3990,7 @@ megasas_get_ld_list(struct megasas_instance *instance)
if (instance->supportmax256vd)
dcmd->mbox.b[0] = 1;
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
dcmd->timeout = 0;
@@ -3965,11 +4028,7 @@ megasas_get_ld_list(struct megasas_instance *instance)
ci,
ci_h);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return ret;
}
@@ -3995,8 +4054,8 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_WARNING
- "megasas:(megasas_ld_list_query): Failed to get cmd\n");
+ dev_warn(&instance->pdev->dev,
+ "megasas_ld_list_query: Failed to get cmd\n");
return -ENOMEM;
}
@@ -4006,8 +4065,8 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
sizeof(struct MR_LD_TARGETID_LIST), &ci_h);
if (!ci) {
- printk(KERN_WARNING
- "megasas: Failed to alloc mem for ld_list_query\n");
+ dev_warn(&instance->pdev->dev,
+ "Failed to alloc mem for ld_list_query\n");
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
@@ -4020,7 +4079,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
dcmd->mbox.b[2] = 1;
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
dcmd->timeout = 0;
@@ -4050,11 +4109,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
pci_free_consistent(instance->pdev, sizeof(struct MR_LD_TARGETID_LIST),
ci, ci_h);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return ret;
}
@@ -4091,18 +4146,17 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
}
- dev_info(&instance->pdev->dev, "Firmware supports %d VD %d PD\n",
- instance->fw_supported_vd_count,
- instance->fw_supported_pd_count);
- dev_info(&instance->pdev->dev, "Driver supports %d VD %d PD\n",
- instance->drv_supported_vd_count,
- instance->drv_supported_pd_count);
- old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
+ dev_info(&instance->pdev->dev,
+ "firmware type\t: %s\n",
+ instance->supportmax256vd ? "Extended VD(240 VD)firmware" :
+ "Legacy(64 VD) firmware");
+
+ old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) *
(instance->fw_supported_vd_count - 1));
- new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
- fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) +
+ new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
+ fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) +
(sizeof(struct MR_LD_SPAN_MAP) *
(instance->drv_supported_vd_count - 1));
@@ -4113,7 +4167,6 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
fusion->current_map_sz = new_map_sz;
else
fusion->current_map_sz = old_map_sz;
-
}
/**
@@ -4139,7 +4192,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas: Failed to get a free cmd\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a free cmd\n");
return -ENOMEM;
}
@@ -4149,7 +4202,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
sizeof(struct megasas_ctrl_info), &ci_h);
if (!ci) {
- printk(KERN_DEBUG "Failed to alloc mem for ctrl info\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc mem for ctrl info\n");
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
@@ -4158,7 +4211,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
dcmd->timeout = 0;
@@ -4181,16 +4234,27 @@ megasas_get_ctrl_info(struct megasas_instance *instance)
le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
le32_to_cpus((u32 *)&ctrl_info->adapterOperations3);
megasas_update_ext_vd_details(instance);
+ instance->use_seqnum_jbod_fp =
+ ctrl_info->adapterOperations3.useSeqNumJbodFP;
+ instance->is_imr = (ctrl_info->memory_size ? 0 : 1);
+ dev_info(&instance->pdev->dev,
+ "controller type\t: %s(%dMB)\n",
+ instance->is_imr ? "iMR" : "MR",
+ le16_to_cpu(ctrl_info->memory_size));
+ instance->disableOnlineCtrlReset =
+ ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
+ dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
+ instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
+ instance->secure_jbod_support =
+ ctrl_info->adapterOperations3.supportSecurityonJBOD;
+ dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n",
+ instance->secure_jbod_support ? "Yes" : "No");
}
pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
ci, ci_h);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return ret;
}
@@ -4229,7 +4293,7 @@ int megasas_set_crash_dump_params(struct megasas_instance *instance,
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
dcmd->mbox.b[0] = crash_buf_state;
dcmd->cmd = MFI_CMD_DCMD;
- dcmd->cmd_status = 0xFF;
+ dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
dcmd->sge_count = 1;
dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
dcmd->timeout = 0;
@@ -4245,11 +4309,7 @@ int megasas_set_crash_dump_params(struct megasas_instance *instance,
else
ret = megasas_issue_polled(instance, cmd);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return ret;
}
@@ -4262,10 +4322,8 @@ int megasas_set_crash_dump_params(struct megasas_instance *instance,
static int
megasas_issue_init_mfi(struct megasas_instance *instance)
{
- u32 context;
-
+ __le32 context;
struct megasas_cmd *cmd;
-
struct megasas_init_frame *init_frame;
struct megasas_init_queue_info *initq_info;
dma_addr_t init_frame_h;
@@ -4300,7 +4358,7 @@ megasas_issue_init_mfi(struct megasas_instance *instance)
initq_info->consumer_index_phys_addr_lo = cpu_to_le32(instance->consumer_h);
init_frame->cmd = MFI_CMD_INIT;
- init_frame->cmd_status = 0xFF;
+ init_frame->cmd_status = MFI_STAT_INVALID_STATUS;
init_frame->queue_info_new_phys_addr_lo =
cpu_to_le32(lower_32_bits(initq_info_h));
init_frame->queue_info_new_phys_addr_hi =
@@ -4318,7 +4376,7 @@ megasas_issue_init_mfi(struct megasas_instance *instance)
*/
if (megasas_issue_polled(instance, cmd)) {
- printk(KERN_ERR "megasas: Failed to init firmware\n");
+ dev_err(&instance->pdev->dev, "Failed to init firmware\n");
megasas_return_cmd(instance, cmd);
goto fail_fw_init;
}
@@ -4354,6 +4412,21 @@ megasas_init_adapter_mfi(struct megasas_instance *instance)
instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
0x10;
/*
+ * For MFI skinny adapters, MEGASAS_SKINNY_INT_CMDS commands
+ * are reserved for IOCTL + driver's internal DCMDs.
+ */
+ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+ instance->max_scsi_cmds = (instance->max_fw_cmds -
+ MEGASAS_SKINNY_INT_CMDS);
+ sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
+ } else {
+ instance->max_scsi_cmds = (instance->max_fw_cmds -
+ MEGASAS_INT_CMDS);
+ sema_init(&instance->ioctl_sem, (MEGASAS_MFI_IOCTL_CMDS));
+ }
+
+ /*
* Create a pool of commands
*/
if (megasas_alloc_cmds(instance))
@@ -4376,7 +4449,7 @@ megasas_init_adapter_mfi(struct megasas_instance *instance)
&instance->reply_queue_h);
if (!instance->reply_queue) {
- printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Out of DMA mem for reply queue\n");
goto fail_reply_queue;
}
@@ -4395,7 +4468,7 @@ megasas_init_adapter_mfi(struct megasas_instance *instance)
(instance->instancet->read_fw_status_reg(reg_set) &
0x04000000);
- printk(KERN_NOTICE "megasas_init_mfi: fw_support_ieee=%d",
+ dev_notice(&instance->pdev->dev, "megasas_init_mfi: fw_support_ieee=%d",
instance->fw_support_ieee);
if (instance->fw_support_ieee)
@@ -4414,6 +4487,163 @@ fail_alloc_cmds:
return 1;
}
+/*
+ * megasas_setup_irqs_msix - register legacy interrupts.
+ * @instance: Adapter soft state
+ *
+ * Do not enable interrupt, only setup ISRs.
+ *
+ * Return 0 on success.
+ */
+static int
+megasas_setup_irqs_ioapic(struct megasas_instance *instance)
+{
+ struct pci_dev *pdev;
+
+ pdev = instance->pdev;
+ instance->irq_context[0].instance = instance;
+ instance->irq_context[0].MSIxIndex = 0;
+ if (request_irq(pdev->irq, instance->instancet->service_isr,
+ IRQF_SHARED, "megasas", &instance->irq_context[0])) {
+ dev_err(&instance->pdev->dev,
+ "Failed to register IRQ from %s %d\n",
+ __func__, __LINE__);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * megasas_setup_irqs_msix - register MSI-x interrupts.
+ * @instance: Adapter soft state
+ * @is_probe: Driver probe check
+ *
+ * Do not enable interrupt, only setup ISRs.
+ *
+ * Return 0 on success.
+ */
+static int
+megasas_setup_irqs_msix(struct megasas_instance *instance, u8 is_probe)
+{
+ int i, j, cpu;
+ struct pci_dev *pdev;
+
+ pdev = instance->pdev;
+
+ /* Try MSI-x */
+ cpu = cpumask_first(cpu_online_mask);
+ for (i = 0; i < instance->msix_vectors; i++) {
+ instance->irq_context[i].instance = instance;
+ instance->irq_context[i].MSIxIndex = i;
+ if (request_irq(instance->msixentry[i].vector,
+ instance->instancet->service_isr, 0, "megasas",
+ &instance->irq_context[i])) {
+ dev_err(&instance->pdev->dev,
+ "Failed to register IRQ for vector %d.\n", i);
+ for (j = 0; j < i; j++) {
+ if (smp_affinity_enable)
+ irq_set_affinity_hint(
+ instance->msixentry[j].vector, NULL);
+ free_irq(instance->msixentry[j].vector,
+ &instance->irq_context[j]);
+ }
+ /* Retry irq register for IO_APIC*/
+ instance->msix_vectors = 0;
+ if (is_probe)
+ return megasas_setup_irqs_ioapic(instance);
+ else
+ return -1;
+ }
+ if (smp_affinity_enable) {
+ if (irq_set_affinity_hint(instance->msixentry[i].vector,
+ get_cpu_mask(cpu)))
+ dev_err(&instance->pdev->dev,
+ "Failed to set affinity hint"
+ " for cpu %d\n", cpu);
+ cpu = cpumask_next(cpu, cpu_online_mask);
+ }
+ }
+ return 0;
+}
+
+/*
+ * megasas_destroy_irqs- unregister interrupts.
+ * @instance: Adapter soft state
+ * return: void
+ */
+static void
+megasas_destroy_irqs(struct megasas_instance *instance) {
+
+ int i;
+
+ if (instance->msix_vectors)
+ for (i = 0; i < instance->msix_vectors; i++) {
+ if (smp_affinity_enable)
+ irq_set_affinity_hint(
+ instance->msixentry[i].vector, NULL);
+ free_irq(instance->msixentry[i].vector,
+ &instance->irq_context[i]);
+ }
+ else
+ free_irq(instance->pdev->irq, &instance->irq_context[0]);
+}
+
+/**
+ * megasas_setup_jbod_map - setup jbod map for FP seq_number.
+ * @instance: Adapter soft state
+ * @is_probe: Driver probe check
+ *
+ * Return 0 on success.
+ */
+void
+megasas_setup_jbod_map(struct megasas_instance *instance)
+{
+ int i;
+ struct fusion_context *fusion = instance->ctrl_context;
+ u32 pd_seq_map_sz;
+
+ pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+ (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1));
+
+ if (reset_devices || !fusion ||
+ !instance->ctrl_info->adapterOperations3.useSeqNumJbodFP) {
+ dev_info(&instance->pdev->dev,
+ "Jbod map is not supported %s %d\n",
+ __func__, __LINE__);
+ instance->use_seqnum_jbod_fp = false;
+ return;
+ }
+
+ if (fusion->pd_seq_sync[0])
+ goto skip_alloc;
+
+ for (i = 0; i < JBOD_MAPS_COUNT; i++) {
+ fusion->pd_seq_sync[i] = dma_alloc_coherent
+ (&instance->pdev->dev, pd_seq_map_sz,
+ &fusion->pd_seq_phys[i], GFP_KERNEL);
+ if (!fusion->pd_seq_sync[i]) {
+ dev_err(&instance->pdev->dev,
+ "Failed to allocate memory from %s %d\n",
+ __func__, __LINE__);
+ if (i == 1) {
+ dma_free_coherent(&instance->pdev->dev,
+ pd_seq_map_sz, fusion->pd_seq_sync[0],
+ fusion->pd_seq_phys[0]);
+ fusion->pd_seq_sync[0] = NULL;
+ }
+ instance->use_seqnum_jbod_fp = false;
+ return;
+ }
+ }
+
+skip_alloc:
+ if (!megasas_sync_pd_seq_num(instance, false) &&
+ !megasas_sync_pd_seq_num(instance, true))
+ instance->use_seqnum_jbod_fp = true;
+ else
+ instance->use_seqnum_jbod_fp = false;
+}
+
/**
* megasas_init_fw - Initializes the FW
* @instance: Adapter soft state
@@ -4432,13 +4662,16 @@ static int megasas_init_fw(struct megasas_instance *instance)
unsigned long bar_list;
int i, loop, fw_msix_count = 0;
struct IOV_111 *iovPtr;
+ struct fusion_context *fusion;
+
+ fusion = instance->ctrl_context;
/* Find first memory bar */
bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
instance->bar = find_first_bit(&bar_list, sizeof(unsigned long));
if (pci_request_selected_regions(instance->pdev, instance->bar,
"megasas: LSI")) {
- printk(KERN_DEBUG "megasas: IO memory region busy!\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "IO memory region busy!\n");
return -EBUSY;
}
@@ -4446,7 +4679,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->reg_set = ioremap_nocache(base_addr, 8192);
if (!instance->reg_set) {
- printk(KERN_DEBUG "megasas: Failed to map IO mem\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to map IO mem\n");
goto fail_ioremap;
}
@@ -4457,6 +4690,10 @@ static int megasas_init_fw(struct megasas_instance *instance)
case PCI_DEVICE_ID_LSI_PLASMA:
case PCI_DEVICE_ID_LSI_INVADER:
case PCI_DEVICE_ID_LSI_FURY:
+ case PCI_DEVICE_ID_LSI_INTRUDER:
+ case PCI_DEVICE_ID_LSI_INTRUDER_24:
+ case PCI_DEVICE_ID_LSI_CUTLASS_52:
+ case PCI_DEVICE_ID_LSI_CUTLASS_53:
instance->instancet = &megasas_instance_template_fusion;
break;
case PCI_DEVICE_ID_LSI_SAS1078R:
@@ -4475,6 +4712,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
case PCI_DEVICE_ID_DELL_PERC5:
default:
instance->instancet = &megasas_instance_template_xscale;
+ instance->allow_fw_scan = 1;
break;
}
@@ -4484,7 +4722,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
(instance, instance->reg_set);
atomic_set(&instance->fw_reset_no_pci_access, 0);
dev_info(&instance->pdev->dev,
- "megasas: FW restarted successfully from %s!\n",
+ "FW restarted successfully from %s!\n",
__func__);
/*waitting for about 30 second before retry*/
@@ -4499,7 +4737,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
* It is used for all MPT based Adapters.
*/
instance->reply_post_host_index_addr[0] =
- (u32 *)((u8 *)instance->reg_set +
+ (u32 __iomem *)((u8 __iomem *)instance->reg_set +
MPI2_REPLY_POST_HOST_INDEX_OFFSET);
/* Check if MSI-X is supported while in ready state */
@@ -4509,36 +4747,32 @@ static int megasas_init_fw(struct megasas_instance *instance)
scratch_pad_2 = readl
(&instance->reg_set->outbound_scratch_pad_2);
/* Check max MSI-X vectors */
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) {
- instance->msix_vectors = (scratch_pad_2
- & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
- fw_msix_count = instance->msix_vectors;
- if (msix_vectors)
- instance->msix_vectors =
- min(msix_vectors,
- instance->msix_vectors);
- } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
- || (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
- /* Invader/Fury supports more than 8 MSI-X */
- instance->msix_vectors = ((scratch_pad_2
- & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
- >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
- fw_msix_count = instance->msix_vectors;
- /* Save 1-15 reply post index address to local memory
- * Index 0 is already saved from reg offset
- * MPI2_REPLY_POST_HOST_INDEX_OFFSET
- */
- for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
- instance->reply_post_host_index_addr[loop] =
- (u32 *)((u8 *)instance->reg_set +
- MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
- + (loop * 0x10));
+ if (fusion) {
+ if (fusion->adapter_type == THUNDERBOLT_SERIES) { /* Thunderbolt Series*/
+ instance->msix_vectors = (scratch_pad_2
+ & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
+ fw_msix_count = instance->msix_vectors;
+ } else { /* Invader series supports more than 8 MSI-x vectors*/
+ instance->msix_vectors = ((scratch_pad_2
+ & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
+ >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
+ fw_msix_count = instance->msix_vectors;
+ /* Save 1-15 reply post index address to local memory
+ * Index 0 is already saved from reg offset
+ * MPI2_REPLY_POST_HOST_INDEX_OFFSET
+ */
+ for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
+ instance->reply_post_host_index_addr[loop] =
+ (u32 __iomem *)
+ ((u8 __iomem *)instance->reg_set +
+ MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
+ + (loop * 0x10));
+ }
}
if (msix_vectors)
instance->msix_vectors = min(msix_vectors,
instance->msix_vectors);
- } else
+ } else /* MFI adapters */
instance->msix_vectors = 1;
/* Don't bother allocating more MSI-X vectors than cpus */
instance->msix_vectors = min(instance->msix_vectors,
@@ -4551,14 +4785,22 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->msix_vectors = i;
else
instance->msix_vectors = 0;
-
- dev_info(&instance->pdev->dev, "[scsi%d]: FW supports"
- "<%d> MSIX vector,Online CPUs: <%d>,"
- "Current MSIX <%d>\n", instance->host->host_no,
- fw_msix_count, (unsigned int)num_online_cpus(),
- instance->msix_vectors);
}
+ dev_info(&instance->pdev->dev,
+ "firmware supports msix\t: (%d)", fw_msix_count);
+ dev_info(&instance->pdev->dev,
+ "current msix/online cpus\t: (%d/%d)\n",
+ instance->msix_vectors, (unsigned int)num_online_cpus());
+
+ tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
+ (unsigned long)instance);
+
+ if (instance->msix_vectors ?
+ megasas_setup_irqs_msix(instance, 1) :
+ megasas_setup_irqs_ioapic(instance))
+ goto fail_setup_irqs;
+
instance->ctrl_info = kzalloc(sizeof(struct megasas_ctrl_info),
GFP_KERNEL);
if (instance->ctrl_info == NULL)
@@ -4574,17 +4816,21 @@ static int megasas_init_fw(struct megasas_instance *instance)
if (instance->instancet->init_adapter(instance))
goto fail_init_adapter;
- printk(KERN_ERR "megasas: INIT adapter done\n");
- /** for passthrough
- * the following function will get the PD LIST.
- */
+ instance->instancet->enable_intr(instance);
+
+ dev_err(&instance->pdev->dev, "INIT adapter done\n");
- memset(instance->pd_list, 0 ,
+ megasas_setup_jbod_map(instance);
+
+ /** for passthrough
+ * the following function will get the PD LIST.
+ */
+ memset(instance->pd_list, 0,
(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
if (megasas_get_pd_list(instance) < 0) {
- printk(KERN_ERR "megasas: failed to get PD list\n");
- goto fail_init_adapter;
+ dev_err(&instance->pdev->dev, "failed to get PD list\n");
+ goto fail_get_pd_list;
}
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
@@ -4608,29 +4854,13 @@ static int megasas_init_fw(struct megasas_instance *instance)
le16_to_cpu(ctrl_info->max_strips_per_io);
max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size);
- tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
+ tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);
- /*Check whether controller is iMR or MR */
- if (ctrl_info->memory_size) {
- instance->is_imr = 0;
- dev_info(&instance->pdev->dev, "Controller type: MR,"
- "Memory size is: %dMB\n",
- le16_to_cpu(ctrl_info->memory_size));
- } else {
- instance->is_imr = 1;
- dev_info(&instance->pdev->dev,
- "Controller type: iMR\n");
- }
- instance->disableOnlineCtrlReset =
- ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
instance->mpio = ctrl_info->adapterOperations2.mpio;
instance->UnevenSpanSupport =
ctrl_info->adapterOperations2.supportUnevenSpans;
if (instance->UnevenSpanSupport) {
struct fusion_context *fusion = instance->ctrl_context;
-
- dev_info(&instance->pdev->dev, "FW supports: "
- "UnevenSpanSupport=%x\n", instance->UnevenSpanSupport);
if (MR_ValidateMapInfo(instance))
fusion->fast_path_io = 1;
else
@@ -4638,18 +4868,22 @@ static int megasas_init_fw(struct megasas_instance *instance)
}
if (ctrl_info->host_interface.SRIOV) {
- if (!ctrl_info->adapterOperations2.activePassive)
- instance->PlasmaFW111 = 1;
-
- if (!instance->PlasmaFW111)
- instance->requestorId =
- ctrl_info->iov.requestorId;
- else {
- iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET);
- instance->requestorId = iovPtr->requestorId;
+ instance->requestorId = ctrl_info->iov.requestorId;
+ if (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) {
+ if (!ctrl_info->adapterOperations2.activePassive)
+ instance->PlasmaFW111 = 1;
+
+ dev_info(&instance->pdev->dev, "SR-IOV: firmware type: %s\n",
+ instance->PlasmaFW111 ? "1.11" : "new");
+
+ if (instance->PlasmaFW111) {
+ iovPtr = (struct IOV_111 *)
+ ((unsigned char *)ctrl_info + IOV_111_OFFSET);
+ instance->requestorId = iovPtr->requestorId;
+ }
}
- dev_warn(&instance->pdev->dev, "I am VF "
- "requestorId %d\n", instance->requestorId);
+ dev_info(&instance->pdev->dev, "SRIOV: VF requestorId %d\n",
+ instance->requestorId);
}
instance->crash_dump_fw_support =
@@ -4657,13 +4891,11 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->crash_dump_drv_support =
(instance->crash_dump_fw_support &&
instance->crash_dump_buf);
- if (instance->crash_dump_drv_support) {
- dev_info(&instance->pdev->dev, "Firmware Crash dump "
- "feature is supported\n");
+ if (instance->crash_dump_drv_support)
megasas_set_crash_dump_params(instance,
MR_CRASH_BUF_TURN_OFF);
- } else {
+ else {
if (instance->crash_dump_buf)
pci_free_consistent(instance->pdev,
CRASH_DMA_BUF_SIZE,
@@ -4672,39 +4904,26 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->crash_dump_buf = NULL;
}
- instance->secure_jbod_support =
- ctrl_info->adapterOperations3.supportSecurityonJBOD;
- if (instance->secure_jbod_support)
- dev_info(&instance->pdev->dev, "Firmware supports Secure JBOD\n");
+
+ dev_info(&instance->pdev->dev,
+ "pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n",
+ le16_to_cpu(ctrl_info->pci.vendor_id),
+ le16_to_cpu(ctrl_info->pci.device_id),
+ le16_to_cpu(ctrl_info->pci.sub_vendor_id),
+ le16_to_cpu(ctrl_info->pci.sub_device_id));
+ dev_info(&instance->pdev->dev, "unevenspan support : %s\n",
+ instance->UnevenSpanSupport ? "yes" : "no");
+ dev_info(&instance->pdev->dev, "firmware crash dump : %s\n",
+ instance->crash_dump_drv_support ? "yes" : "no");
+ dev_info(&instance->pdev->dev, "jbod sync map : %s\n",
+ instance->use_seqnum_jbod_fp ? "yes" : "no");
+
+
instance->max_sectors_per_req = instance->max_num_sge *
- PAGE_SIZE / 512;
+ SGE_BUFFER_SIZE / 512;
if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
instance->max_sectors_per_req = tmp_sectors;
- /*
- * 1. For fusion adapters, 3 commands for IOCTL and 5 commands
- * for driver's internal DCMDs.
- * 2. For MFI skinny adapters, 5 commands for IOCTL + driver's
- * internal DCMDs.
- * 3. For rest of MFI adapters, 27 commands reserved for IOCTLs
- * and 5 commands for drivers's internal DCMD.
- */
- if (instance->ctrl_context) {
- instance->max_scsi_cmds = instance->max_fw_cmds -
- (MEGASAS_FUSION_INTERNAL_CMDS +
- MEGASAS_FUSION_IOCTL_CMDS);
- sema_init(&instance->ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS);
- } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
- instance->max_scsi_cmds = instance->max_fw_cmds -
- MEGASAS_SKINNY_INT_CMDS;
- sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
- } else {
- instance->max_scsi_cmds = instance->max_fw_cmds -
- MEGASAS_INT_CMDS;
- sema_init(&instance->ioctl_sem, (MEGASAS_INT_CMDS - 5));
- }
-
/* Check for valid throttlequeuedepth module parameter */
if (throttlequeuedepth &&
throttlequeuedepth <= instance->max_scsi_cmds)
@@ -4713,12 +4932,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->throttlequeuedepth =
MEGASAS_THROTTLE_QUEUE_DEPTH;
- /*
- * Setup tasklet for cmd completion
- */
-
- tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
- (unsigned long)instance);
/* Launch SR-IOV heartbeat timer */
if (instance->requestorId) {
@@ -4733,7 +4946,14 @@ static int megasas_init_fw(struct megasas_instance *instance)
return 0;
+fail_get_pd_list:
+ instance->instancet->disable_intr(instance);
fail_init_adapter:
+ megasas_destroy_irqs(instance);
+fail_setup_irqs:
+ if (instance->msix_vectors)
+ pci_disable_msix(instance->pdev);
+ instance->msix_vectors = 0;
fail_ready_state:
kfree(instance->ctrl_info);
instance->ctrl_info = NULL;
@@ -4747,7 +4967,7 @@ fail_ready_state:
/**
* megasas_release_mfi - Reverses the FW initialization
- * @intance: Adapter soft state
+ * @instance: Adapter soft state
*/
static void megasas_release_mfi(struct megasas_instance *instance)
{
@@ -4822,21 +5042,17 @@ megasas_get_seq_num(struct megasas_instance *instance,
/*
* Copy the data back into callers buffer
*/
- eli->newest_seq_num = le32_to_cpu(el_info->newest_seq_num);
- eli->oldest_seq_num = le32_to_cpu(el_info->oldest_seq_num);
- eli->clear_seq_num = le32_to_cpu(el_info->clear_seq_num);
- eli->shutdown_seq_num = le32_to_cpu(el_info->shutdown_seq_num);
- eli->boot_seq_num = le32_to_cpu(el_info->boot_seq_num);
+ eli->newest_seq_num = el_info->newest_seq_num;
+ eli->oldest_seq_num = el_info->oldest_seq_num;
+ eli->clear_seq_num = el_info->clear_seq_num;
+ eli->shutdown_seq_num = el_info->shutdown_seq_num;
+ eli->boot_seq_num = el_info->boot_seq_num;
}
pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
el_info, el_info_h);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return 0;
}
@@ -4877,8 +5093,8 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
if (instance->aen_cmd) {
- prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1];
- prev_aen.members.locale = le16_to_cpu(prev_aen.members.locale);
+ prev_aen.word =
+ le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]);
/*
* A class whose enum value is smaller is inclusive of all
@@ -4910,7 +5126,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
aen_cmd, 30);
if (ret_val) {
- printk(KERN_DEBUG "megasas: Failed to abort "
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to abort "
"previous AEN command\n");
return ret_val;
}
@@ -4990,7 +5206,7 @@ static int megasas_start_aen(struct megasas_instance *instance)
class_locale.members.class = MR_EVT_CLASS_DEBUG;
return megasas_register_aen(instance,
- eli.newest_seq_num + 1,
+ le32_to_cpu(eli.newest_seq_num) + 1,
class_locale.word);
}
@@ -5028,7 +5244,7 @@ static int megasas_io_attach(struct megasas_instance *instance)
(max_sectors <= MEGASAS_MAX_SECTORS)) {
instance->max_sectors_per_req = max_sectors;
} else {
- printk(KERN_INFO "megasas: max_sectors should be > 0"
+ dev_info(&instance->pdev->dev, "max_sectors should be > 0"
"and <= %d (or < 1MB for GEN2 controller)\n",
instance->max_sectors_per_req);
}
@@ -5043,10 +5259,7 @@ static int megasas_io_attach(struct megasas_instance *instance)
host->max_cmd_len = 16;
/* Fusion only supports host reset */
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+ if (instance->ctrl_context) {
host->hostt->eh_device_reset_handler = NULL;
host->hostt->eh_bus_reset_handler = NULL;
}
@@ -5055,7 +5268,9 @@ static int megasas_io_attach(struct megasas_instance *instance)
* Notify the mid-layer about the new controller
*/
if (scsi_add_host(host, &instance->pdev->dev)) {
- printk(KERN_DEBUG "megasas: scsi_add_host failed\n");
+ dev_err(&instance->pdev->dev,
+ "Failed to add host from %s %d\n",
+ __func__, __LINE__);
return -ENODEV;
}
@@ -5066,7 +5281,7 @@ static int
megasas_set_dma_mask(struct pci_dev *pdev)
{
/*
- * All our contollers are capable of performing 64-bit DMA
+ * All our controllers are capable of performing 64-bit DMA
*/
if (IS_DMA64) {
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
@@ -5106,7 +5321,7 @@ fail_set_dma_mask:
static int megasas_probe_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
- int rval, pos, i, j, cpu;
+ int rval, pos;
struct Scsi_Host *host;
struct megasas_instance *instance;
u16 control = 0;
@@ -5129,16 +5344,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
}
/*
- * Announce PCI information
- */
- printk(KERN_INFO "megasas: %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
- pdev->vendor, pdev->device, pdev->subsystem_vendor,
- pdev->subsystem_device);
-
- printk("bus %d:slot %d:func %d\n",
- pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
-
- /*
* PCI prepping: enable device set bus mastering and dma mask
*/
rval = pci_enable_device_mem(pdev);
@@ -5156,13 +5361,13 @@ static int megasas_probe_one(struct pci_dev *pdev,
sizeof(struct megasas_instance));
if (!host) {
- printk(KERN_DEBUG "megasas: scsi_host_alloc failed\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "scsi_host_alloc failed\n");
goto fail_alloc_instance;
}
instance = (struct megasas_instance *)host->hostdata;
memset(instance, 0, sizeof(*instance));
- atomic_set( &instance->fw_reset_no_pci_access, 0 );
+ atomic_set(&instance->fw_reset_no_pci_access, 0);
instance->pdev = pdev;
switch (instance->pdev->device) {
@@ -5170,21 +5375,28 @@ static int megasas_probe_one(struct pci_dev *pdev,
case PCI_DEVICE_ID_LSI_PLASMA:
case PCI_DEVICE_ID_LSI_INVADER:
case PCI_DEVICE_ID_LSI_FURY:
+ case PCI_DEVICE_ID_LSI_INTRUDER:
+ case PCI_DEVICE_ID_LSI_INTRUDER_24:
+ case PCI_DEVICE_ID_LSI_CUTLASS_52:
+ case PCI_DEVICE_ID_LSI_CUTLASS_53:
{
instance->ctrl_context_pages =
get_order(sizeof(struct fusion_context));
instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL,
instance->ctrl_context_pages);
if (!instance->ctrl_context) {
- printk(KERN_DEBUG "megasas: Failed to allocate "
+ dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate "
"memory for Fusion context info\n");
goto fail_alloc_dma_buf;
}
fusion = instance->ctrl_context;
memset(fusion, 0,
((1 << PAGE_SHIFT) << instance->ctrl_context_pages));
- INIT_LIST_HEAD(&fusion->cmd_pool);
- spin_lock_init(&fusion->mpt_pool_lock);
+ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA))
+ fusion->adapter_type = THUNDERBOLT_SERIES;
+ else
+ fusion->adapter_type = INVADER_SERIES;
}
break;
default: /* For all other supported controllers */
@@ -5197,7 +5409,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
&instance->consumer_h);
if (!instance->producer || !instance->consumer) {
- printk(KERN_DEBUG "megasas: Failed to allocate"
+ dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate"
"memory for producer, consumer\n");
goto fail_alloc_dma_buf;
}
@@ -5207,6 +5419,13 @@ static int megasas_probe_one(struct pci_dev *pdev,
break;
}
+ instance->system_info_buf = pci_zalloc_consistent(pdev,
+ sizeof(struct MR_DRV_SYSTEM_INFO),
+ &instance->system_info_h);
+
+ if (!instance->system_info_buf)
+ dev_info(&instance->pdev->dev, "Can't allocate system info buffer\n");
+
/* Crash dump feature related initialisation*/
instance->drv_buf_index = 0;
instance->drv_buf_alloc = 0;
@@ -5221,7 +5440,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
CRASH_DMA_BUF_SIZE,
&instance->crash_dump_h);
if (!instance->crash_dump_buf)
- dev_err(&instance->pdev->dev, "Can't allocate Firmware "
+ dev_err(&pdev->dev, "Can't allocate Firmware "
"crash dump DMA buffer\n");
megasas_poll_wait_aen = 0;
@@ -5237,7 +5456,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
&instance->evt_detail_h);
if (!instance->evt_detail) {
- printk(KERN_DEBUG "megasas: Failed to allocate memory for "
+ dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate memory for "
"event detail structure\n");
goto fail_alloc_dma_buf;
}
@@ -5280,10 +5499,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
instance->disableOnlineCtrlReset = 1;
instance->UnevenSpanSupport = 0;
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+ if (instance->ctrl_context) {
INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq);
} else
@@ -5301,7 +5517,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
pci_alloc_consistent(pdev, sizeof(struct MR_LD_VF_AFFILIATION_111),
&instance->vf_affiliation_111_h);
if (!instance->vf_affiliation_111)
- printk(KERN_WARNING "megasas: Can't allocate "
+ dev_warn(&pdev->dev, "Can't allocate "
"memory for VF affiliation buffer\n");
} else {
instance->vf_affiliation =
@@ -5310,60 +5526,11 @@ static int megasas_probe_one(struct pci_dev *pdev,
sizeof(struct MR_LD_VF_AFFILIATION),
&instance->vf_affiliation_h);
if (!instance->vf_affiliation)
- printk(KERN_WARNING "megasas: Can't allocate "
+ dev_warn(&pdev->dev, "Can't allocate "
"memory for VF affiliation buffer\n");
}
}
-retry_irq_register:
- /*
- * Register IRQ
- */
- if (instance->msix_vectors) {
- cpu = cpumask_first(cpu_online_mask);
- for (i = 0; i < instance->msix_vectors; i++) {
- instance->irq_context[i].instance = instance;
- instance->irq_context[i].MSIxIndex = i;
- if (request_irq(instance->msixentry[i].vector,
- instance->instancet->service_isr, 0,
- "megasas",
- &instance->irq_context[i])) {
- printk(KERN_DEBUG "megasas: Failed to "
- "register IRQ for vector %d.\n", i);
- for (j = 0; j < i; j++) {
- if (smp_affinity_enable)
- irq_set_affinity_hint(
- instance->msixentry[j].vector, NULL);
- free_irq(
- instance->msixentry[j].vector,
- &instance->irq_context[j]);
- }
- /* Retry irq register for IO_APIC */
- instance->msix_vectors = 0;
- goto retry_irq_register;
- }
- if (smp_affinity_enable) {
- if (irq_set_affinity_hint(instance->msixentry[i].vector,
- get_cpu_mask(cpu)))
- dev_err(&instance->pdev->dev,
- "Error setting affinity hint "
- "for cpu %d\n", cpu);
- cpu = cpumask_next(cpu, cpu_online_mask);
- }
- }
- } else {
- instance->irq_context[0].instance = instance;
- instance->irq_context[0].MSIxIndex = 0;
- if (request_irq(pdev->irq, instance->instancet->service_isr,
- IRQF_SHARED, "megasas",
- &instance->irq_context[0])) {
- printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
- goto fail_irq;
- }
- }
-
- instance->instancet->enable_intr(instance);
-
/*
* Store instance in PCI softstate
*/
@@ -5393,7 +5560,7 @@ retry_irq_register:
* Initiate AEN (Asynchronous Event Notification)
*/
if (megasas_start_aen(instance)) {
- printk(KERN_DEBUG "megasas: start aen failed\n");
+ dev_printk(KERN_DEBUG, &pdev->dev, "start aen failed\n");
goto fail_start_aen;
}
@@ -5403,35 +5570,23 @@ retry_irq_register:
return 0;
- fail_start_aen:
- fail_io_attach:
+fail_start_aen:
+fail_io_attach:
megasas_mgmt_info.count--;
megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL;
megasas_mgmt_info.max_index--;
instance->instancet->disable_intr(instance);
- if (instance->msix_vectors)
- for (i = 0; i < instance->msix_vectors; i++) {
- if (smp_affinity_enable)
- irq_set_affinity_hint(
- instance->msixentry[i].vector, NULL);
- free_irq(instance->msixentry[i].vector,
- &instance->irq_context[i]);
- }
- else
- free_irq(instance->pdev->irq, &instance->irq_context[0]);
-fail_irq:
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+ megasas_destroy_irqs(instance);
+
+ if (instance->ctrl_context)
megasas_release_fusion(instance);
else
megasas_release_mfi(instance);
- fail_init_mfi:
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);
- fail_alloc_dma_buf:
+fail_init_mfi:
+fail_alloc_dma_buf:
if (instance->evt_detail)
pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
instance->evt_detail,
@@ -5445,8 +5600,8 @@ fail_irq:
instance->consumer_h);
scsi_host_put(host);
- fail_alloc_instance:
- fail_set_dma_mask:
+fail_alloc_instance:
+fail_set_dma_mask:
pci_disable_device(pdev);
return -ENODEV;
@@ -5487,13 +5642,7 @@ static void megasas_flush_cache(struct megasas_instance *instance)
dev_err(&instance->pdev->dev, "Command timedout"
" from %s\n", __func__);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
-
- return;
+ megasas_return_cmd(instance, cmd);
}
/**
@@ -5517,10 +5666,14 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
if (instance->aen_cmd)
megasas_issue_blocked_abort_cmd(instance,
- instance->aen_cmd, 30);
+ instance->aen_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
if (instance->map_update_cmd)
megasas_issue_blocked_abort_cmd(instance,
- instance->map_update_cmd, 30);
+ instance->map_update_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
+ if (instance->jbod_seq_cmd)
+ megasas_issue_blocked_abort_cmd(instance,
+ instance->jbod_seq_cmd, MEGASAS_BLOCKED_CMD_TIMEOUT);
+
dcmd = &cmd->frame->dcmd;
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
@@ -5538,13 +5691,7 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
dev_err(&instance->pdev->dev, "Command timedout"
"from %s\n", __func__);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
-
- return;
+ megasas_return_cmd(instance, cmd);
}
#ifdef CONFIG_PM
@@ -5558,7 +5705,6 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct Scsi_Host *host;
struct megasas_instance *instance;
- int i;
instance = pci_get_drvdata(pdev);
host = instance->host;
@@ -5583,16 +5729,8 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
pci_set_drvdata(instance->pdev, instance);
instance->instancet->disable_intr(instance);
- if (instance->msix_vectors)
- for (i = 0; i < instance->msix_vectors; i++) {
- if (smp_affinity_enable)
- irq_set_affinity_hint(
- instance->msixentry[i].vector, NULL);
- free_irq(instance->msixentry[i].vector,
- &instance->irq_context[i]);
- }
- else
- free_irq(instance->pdev->irq, &instance->irq_context[0]);
+ megasas_destroy_irqs(instance);
+
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);
@@ -5611,7 +5749,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
static int
megasas_resume(struct pci_dev *pdev)
{
- int rval, i, j, cpu;
+ int rval;
struct Scsi_Host *host;
struct megasas_instance *instance;
@@ -5627,7 +5765,7 @@ megasas_resume(struct pci_dev *pdev)
rval = pci_enable_device_mem(pdev);
if (rval) {
- printk(KERN_ERR "megasas: Enable device failed\n");
+ dev_err(&pdev->dev, "Enable device failed\n");
return rval;
}
@@ -5654,12 +5792,7 @@ megasas_resume(struct pci_dev *pdev)
instance->msix_vectors))
goto fail_reenable_msix;
- switch (instance->pdev->device) {
- case PCI_DEVICE_ID_LSI_FUSION:
- case PCI_DEVICE_ID_LSI_PLASMA:
- case PCI_DEVICE_ID_LSI_INVADER:
- case PCI_DEVICE_ID_LSI_FURY:
- {
+ if (instance->ctrl_context) {
megasas_reset_reply_desc(instance);
if (megasas_ioc_init_fusion(instance)) {
megasas_free_cmds(instance);
@@ -5668,63 +5801,20 @@ megasas_resume(struct pci_dev *pdev)
}
if (!megasas_get_map_info(instance))
megasas_sync_map_info(instance);
- }
- break;
- default:
+ } else {
*instance->producer = 0;
*instance->consumer = 0;
if (megasas_issue_init_mfi(instance))
goto fail_init_mfi;
- break;
}
tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
(unsigned long)instance);
- /*
- * Register IRQ
- */
- if (instance->msix_vectors) {
- cpu = cpumask_first(cpu_online_mask);
- for (i = 0 ; i < instance->msix_vectors; i++) {
- instance->irq_context[i].instance = instance;
- instance->irq_context[i].MSIxIndex = i;
- if (request_irq(instance->msixentry[i].vector,
- instance->instancet->service_isr, 0,
- "megasas",
- &instance->irq_context[i])) {
- printk(KERN_DEBUG "megasas: Failed to "
- "register IRQ for vector %d.\n", i);
- for (j = 0; j < i; j++) {
- if (smp_affinity_enable)
- irq_set_affinity_hint(
- instance->msixentry[j].vector, NULL);
- free_irq(
- instance->msixentry[j].vector,
- &instance->irq_context[j]);
- }
- goto fail_irq;
- }
-
- if (smp_affinity_enable) {
- if (irq_set_affinity_hint(instance->msixentry[i].vector,
- get_cpu_mask(cpu)))
- dev_err(&instance->pdev->dev, "Error "
- "setting affinity hint for cpu "
- "%d\n", cpu);
- cpu = cpumask_next(cpu, cpu_online_mask);
- }
- }
- } else {
- instance->irq_context[0].instance = instance;
- instance->irq_context[0].MSIxIndex = 0;
- if (request_irq(pdev->irq, instance->instancet->service_isr,
- IRQF_SHARED, "megasas",
- &instance->irq_context[0])) {
- printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
- goto fail_irq;
- }
- }
+ if (instance->msix_vectors ?
+ megasas_setup_irqs_msix(instance, 0) :
+ megasas_setup_irqs_ioapic(instance))
+ goto fail_init_mfi;
/* Re-launch SR-IOV heartbeat timer */
if (instance->requestorId) {
@@ -5733,22 +5823,24 @@ megasas_resume(struct pci_dev *pdev)
&instance->sriov_heartbeat_timer,
megasas_sriov_heartbeat_handler,
MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
- else
+ else {
instance->skip_heartbeat_timer_del = 1;
+ goto fail_init_mfi;
+ }
}
instance->instancet->enable_intr(instance);
+ megasas_setup_jbod_map(instance);
instance->unload = 0;
/*
* Initiate AEN (Asynchronous Event Notification)
*/
if (megasas_start_aen(instance))
- printk(KERN_ERR "megasas: Start AEN failed\n");
+ dev_err(&instance->pdev->dev, "Start AEN failed\n");
return 0;
-fail_irq:
fail_init_mfi:
if (instance->evt_detail)
pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
@@ -5786,6 +5878,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
struct Scsi_Host *host;
struct megasas_instance *instance;
struct fusion_context *fusion;
+ u32 pd_seq_map_sz;
instance = pci_get_drvdata(pdev);
instance->unload = 1;
@@ -5829,25 +5922,16 @@ static void megasas_detach_one(struct pci_dev *pdev)
instance->instancet->disable_intr(instance);
- if (instance->msix_vectors)
- for (i = 0; i < instance->msix_vectors; i++) {
- if (smp_affinity_enable)
- irq_set_affinity_hint(
- instance->msixentry[i].vector, NULL);
- free_irq(instance->msixentry[i].vector,
- &instance->irq_context[i]);
- }
- else
- free_irq(instance->pdev->irq, &instance->irq_context[0]);
+ megasas_destroy_irqs(instance);
+
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);
- switch (instance->pdev->device) {
- case PCI_DEVICE_ID_LSI_FUSION:
- case PCI_DEVICE_ID_LSI_PLASMA:
- case PCI_DEVICE_ID_LSI_INVADER:
- case PCI_DEVICE_ID_LSI_FURY:
+ if (instance->ctrl_context) {
megasas_release_fusion(instance);
+ pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+ (sizeof(struct MR_PD_CFG_SEQ) *
+ (MAX_PHYSICAL_DEVICES - 1));
for (i = 0; i < 2 ; i++) {
if (fusion->ld_map[i])
dma_free_coherent(&instance->pdev->dev,
@@ -5857,11 +5941,15 @@ static void megasas_detach_one(struct pci_dev *pdev)
if (fusion->ld_drv_map[i])
free_pages((ulong)fusion->ld_drv_map[i],
fusion->drv_map_pages);
+ if (fusion->pd_seq_sync)
+ dma_free_coherent(&instance->pdev->dev,
+ pd_seq_map_sz,
+ fusion->pd_seq_sync[i],
+ fusion->pd_seq_phys[i]);
}
free_pages((ulong)instance->ctrl_context,
instance->ctrl_context_pages);
- break;
- default:
+ } else {
megasas_release_mfi(instance);
pci_free_consistent(pdev, sizeof(u32),
instance->producer,
@@ -5869,7 +5957,6 @@ static void megasas_detach_one(struct pci_dev *pdev)
pci_free_consistent(pdev, sizeof(u32),
instance->consumer,
instance->consumer_h);
- break;
}
kfree(instance->ctrl_info);
@@ -5899,11 +5986,13 @@ static void megasas_detach_one(struct pci_dev *pdev)
pci_free_consistent(pdev, CRASH_DMA_BUF_SIZE,
instance->crash_dump_buf, instance->crash_dump_h);
+ if (instance->system_info_buf)
+ pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO),
+ instance->system_info_buf, instance->system_info_h);
+
scsi_host_put(host);
pci_disable_device(pdev);
-
- return;
}
/**
@@ -5912,23 +6001,14 @@ static void megasas_detach_one(struct pci_dev *pdev)
*/
static void megasas_shutdown(struct pci_dev *pdev)
{
- int i;
struct megasas_instance *instance = pci_get_drvdata(pdev);
instance->unload = 1;
megasas_flush_cache(instance);
megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
instance->instancet->disable_intr(instance);
- if (instance->msix_vectors)
- for (i = 0; i < instance->msix_vectors; i++) {
- if (smp_affinity_enable)
- irq_set_affinity_hint(
- instance->msixentry[i].vector, NULL);
- free_irq(instance->msixentry[i].vector,
- &instance->irq_context[i]);
- }
- else
- free_irq(instance->pdev->irq, &instance->irq_context[0]);
+ megasas_destroy_irqs(instance);
+
if (instance->msix_vectors)
pci_disable_msix(instance->pdev);
}
@@ -5981,11 +6061,11 @@ static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
{
unsigned int mask;
unsigned long flags;
+
poll_wait(file, &megasas_poll_wait, wait);
spin_lock_irqsave(&poll_aen_lock, flags);
if (megasas_poll_wait_aen)
- mask = (POLLIN | POLLRDNORM);
-
+ mask = (POLLIN | POLLRDNORM);
else
mask = 0;
megasas_poll_wait_aen = 0;
@@ -5999,8 +6079,7 @@ static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
* @cmd: MFI command frame
*/
-static int megasas_set_crash_dump_params_ioctl(
- struct megasas_cmd *cmd)
+static int megasas_set_crash_dump_params_ioctl(struct megasas_cmd *cmd)
{
struct megasas_instance *local_instance;
int i, error = 0;
@@ -6054,14 +6133,14 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
memset(kbuff_arr, 0, sizeof(kbuff_arr));
if (ioc->sge_count > MAX_IOCTL_SGE) {
- printk(KERN_DEBUG "megasas: SGE count [%d] > max limit [%d]\n",
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "SGE count [%d] > max limit [%d]\n",
ioc->sge_count, MAX_IOCTL_SGE);
return -EINVAL;
}
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas: Failed to get a cmd packet\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n");
return -ENOMEM;
}
@@ -6106,8 +6185,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
ioc->sgl[i].iov_len,
&buf_handle, GFP_KERNEL);
if (!kbuff_arr[i]) {
- printk(KERN_DEBUG "megasas: Failed to alloc "
- "kernel SGL buffer for IOCTL \n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc "
+ "kernel SGL buffer for IOCTL\n");
error = -ENOMEM;
goto out;
}
@@ -6180,7 +6259,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
sense, ioc->sense_len)) {
- printk(KERN_ERR "megasas: Failed to copy out to user "
+ dev_err(&instance->pdev->dev, "Failed to copy out to user "
"sense data\n");
error = -EFAULT;
goto out;
@@ -6192,11 +6271,11 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
*/
if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
&cmd->frame->hdr.cmd_status, sizeof(u8))) {
- printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error copying out cmd_status\n");
error = -EFAULT;
}
- out:
+out:
if (sense) {
dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
sense, sense_handle);
@@ -6211,11 +6290,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
kbuff_arr[i] = NULL;
}
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return error;
}
@@ -6256,7 +6331,7 @@ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
}
if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
- printk(KERN_ERR "Controller in crit error\n");
+ dev_err(&instance->pdev->dev, "Controller in crit error\n");
error = -ENODEV;
goto out_kfree_ioc;
}
@@ -6281,7 +6356,7 @@ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
spin_unlock_irqrestore(&instance->hba_lock, flags);
if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
- printk(KERN_NOTICE "megasas: waiting"
+ dev_notice(&instance->pdev->dev, "waiting"
"for controller reset to finish\n");
}
@@ -6292,7 +6367,7 @@ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
spin_unlock_irqrestore(&instance->hba_lock, flags);
- printk(KERN_ERR "megaraid_sas: timed out while"
+ dev_err(&instance->pdev->dev, "timed out while"
"waiting for HBA to recover\n");
error = -ENODEV;
goto out_up;
@@ -6300,10 +6375,10 @@ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
spin_unlock_irqrestore(&instance->hba_lock, flags);
error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
- out_up:
+out_up:
up(&instance->ioctl_sem);
- out_kfree_ioc:
+out_kfree_ioc:
kfree(ioc);
return error;
}
@@ -6351,7 +6426,7 @@ static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
spin_unlock_irqrestore(&instance->hba_lock, flags);
if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
- printk(KERN_NOTICE "megasas: waiting for"
+ dev_notice(&instance->pdev->dev, "waiting for"
"controller reset to finish\n");
}
@@ -6361,8 +6436,8 @@ static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
spin_lock_irqsave(&instance->hba_lock, flags);
if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
spin_unlock_irqrestore(&instance->hba_lock, flags);
- printk(KERN_ERR "megaraid_sas: timed out while waiting"
- "for HBA to recover.\n");
+ dev_err(&instance->pdev->dev, "timed out while waiting"
+ "for HBA to recover\n");
return -ENODEV;
}
spin_unlock_irqrestore(&instance->hba_lock, flags);
@@ -6401,6 +6476,9 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
int i;
int error = 0;
compat_uptr_t ptr;
+ unsigned long local_raw_ptr;
+ u32 local_sense_off;
+ u32 local_sense_len;
if (clear_user(ioc, sizeof(*ioc)))
return -EFAULT;
@@ -6418,9 +6496,15 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
* sense_len is not null, so prepare the 64bit value under
* the same condition.
*/
- if (ioc->sense_len) {
+ if (get_user(local_raw_ptr, ioc->frame.raw) ||
+ get_user(local_sense_off, &ioc->sense_off) ||
+ get_user(local_sense_len, &ioc->sense_len))
+ return -EFAULT;
+
+
+ if (local_sense_len) {
void __user **sense_ioc_ptr =
- (void __user **)(ioc->frame.raw + ioc->sense_off);
+ (void __user **)((u8*)local_raw_ptr + local_sense_off);
compat_uptr_t *sense_cioc_ptr =
(compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
if (get_user(ptr, sense_cioc_ptr) ||
@@ -6502,6 +6586,15 @@ static ssize_t megasas_sysfs_show_version(struct device_driver *dd, char *buf)
static DRIVER_ATTR(version, S_IRUGO, megasas_sysfs_show_version, NULL);
static ssize_t
+megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
+{
+ return snprintf(buf, strlen(MEGASAS_RELDATE) + 2, "%s\n",
+ MEGASAS_RELDATE);
+}
+
+static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date, NULL);
+
+static ssize_t
megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
{
return sprintf(buf, "%u\n", support_poll_for_event);
@@ -6529,7 +6622,8 @@ static ssize_t
megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
{
int retval = count;
- if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
+
+ if (sscanf(buf, "%u", &megasas_dbg_lvl) < 1) {
printk(KERN_ERR "megasas: could not set dbg_lvl\n");
retval = -EINVAL;
}
@@ -6569,7 +6663,7 @@ megasas_aen_polling(struct work_struct *work)
if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL)
break;
if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
- printk(KERN_NOTICE "megasas: %s waiting for "
+ dev_notice(&instance->pdev->dev, "%s waiting for "
"controller reset to finish for scsi%d\n",
__func__, instance->host->host_no);
}
@@ -6579,6 +6673,7 @@ megasas_aen_polling(struct work_struct *work)
instance->ev = NULL;
host = instance->host;
if (instance->evt_detail) {
+ megasas_decode_evt(instance);
switch (le32_to_cpu(instance->evt_detail->code)) {
case MR_EVT_PD_INSERTED:
@@ -6591,14 +6686,12 @@ megasas_aen_polling(struct work_struct *work)
pd_index =
(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
- sdev1 =
- scsi_device_lookup(host, i, j, 0);
+ sdev1 = scsi_device_lookup(host, i, j, 0);
if (instance->pd_list[pd_index].driveState
== MR_PD_STATE_SYSTEM) {
- if (!sdev1) {
+ if (!sdev1)
scsi_add_device(host, i, j, 0);
- }
if (sdev1)
scsi_device_put(sdev1);
@@ -6619,14 +6712,12 @@ megasas_aen_polling(struct work_struct *work)
pd_index =
(i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
- sdev1 =
- scsi_device_lookup(host, i, j, 0);
+ sdev1 = scsi_device_lookup(host, i, j, 0);
if (instance->pd_list[pd_index].driveState
== MR_PD_STATE_SYSTEM) {
- if (sdev1) {
+ if (sdev1)
scsi_device_put(sdev1);
- }
} else {
if (sdev1) {
scsi_remove_device(sdev1);
@@ -6643,8 +6734,7 @@ megasas_aen_polling(struct work_struct *work)
case MR_EVT_CFG_CLEARED:
case MR_EVT_LD_DELETED:
if (!instance->requestorId ||
- (instance->requestorId &&
- megasas_get_ld_vf_affiliation(instance, 0))) {
+ megasas_get_ld_vf_affiliation(instance, 0)) {
if (megasas_ld_list_query(instance,
MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
megasas_get_ld_list(instance);
@@ -6675,8 +6765,7 @@ megasas_aen_polling(struct work_struct *work)
break;
case MR_EVT_LD_CREATED:
if (!instance->requestorId ||
- (instance->requestorId &&
- megasas_get_ld_vf_affiliation(instance, 0))) {
+ megasas_get_ld_vf_affiliation(instance, 0)) {
if (megasas_ld_list_query(instance,
MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
megasas_get_ld_list(instance);
@@ -6706,18 +6795,21 @@ megasas_aen_polling(struct work_struct *work)
case MR_EVT_LD_STATE_CHANGE:
doscan = 1;
break;
+ case MR_EVT_CTRL_PROP_CHANGED:
+ megasas_get_ctrl_info(instance);
+ break;
default:
doscan = 0;
break;
}
} else {
- printk(KERN_ERR "invalid evt_detail!\n");
+ dev_err(&instance->pdev->dev, "invalid evt_detail!\n");
kfree(ev);
return;
}
if (doscan) {
- printk(KERN_INFO "megaraid_sas: scanning for scsi%d...\n",
+ dev_info(&instance->pdev->dev, "scanning for scsi%d...\n",
instance->host->host_no);
if (megasas_get_pd_list(instance) == 0) {
for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
@@ -6742,8 +6834,7 @@ megasas_aen_polling(struct work_struct *work)
}
if (!instance->requestorId ||
- (instance->requestorId &&
- megasas_get_ld_vf_affiliation(instance, 0))) {
+ megasas_get_ld_vf_affiliation(instance, 0)) {
if (megasas_ld_list_query(instance,
MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
megasas_get_ld_list(instance);
@@ -6772,7 +6863,7 @@ megasas_aen_polling(struct work_struct *work)
}
}
- if ( instance->aen_cmd != NULL ) {
+ if (instance->aen_cmd != NULL) {
kfree(ev);
return ;
}
@@ -6789,7 +6880,7 @@ megasas_aen_polling(struct work_struct *work)
mutex_unlock(&instance->aen_mutex);
if (error)
- printk(KERN_ERR "register aen failed error %x\n", error);
+ dev_err(&instance->pdev->dev, "register aen failed error %x\n", error);
kfree(ev);
}
@@ -6841,6 +6932,11 @@ static int __init megasas_init(void)
goto err_dcf_attr_ver;
rval = driver_create_file(&megasas_pci_driver.driver,
+ &driver_attr_release_date);
+ if (rval)
+ goto err_dcf_rel_date;
+
+ rval = driver_create_file(&megasas_pci_driver.driver,
&driver_attr_support_poll_for_event);
if (rval)
goto err_dcf_support_poll_for_event;
@@ -6863,6 +6959,9 @@ err_dcf_dbg_lvl:
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_support_poll_for_event);
err_dcf_support_poll_for_event:
+ driver_remove_file(&megasas_pci_driver.driver,
+ &driver_attr_release_date);
+err_dcf_rel_date:
driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
err_dcf_attr_ver:
pci_unregister_driver(&megasas_pci_driver);
@@ -6882,6 +6981,8 @@ static void __exit megasas_exit(void)
&driver_attr_support_poll_for_event);
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_support_device_change);
+ driver_remove_file(&megasas_pci_driver.driver,
+ &driver_attr_release_date);
driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
pci_unregister_driver(&megasas_pci_driver);
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c b/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c
index 4f7228786..741509b35 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -66,7 +66,15 @@ MODULE_PARM_DESC(lb_pending_cmds, "Change raid-1 load balancing outstanding "
#define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
#define MR_LD_STATE_OPTIMAL 3
+
+#ifdef FALSE
+#undef FALSE
+#endif
#define FALSE 0
+
+#ifdef TRUE
+#undef TRUE
+#endif
#define TRUE 1
#define SPAN_DEBUG 0
@@ -142,7 +150,7 @@ u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map)
return le16_to_cpu(map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef);
}
-u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map)
+__le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map)
{
return map->raidMap.devHndlInfo[pd].curDevHdl;
}
@@ -733,14 +741,12 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
u8 physArm, span;
u64 row;
u8 retval = TRUE;
- u8 do_invader = 0;
u64 *pdBlock = &io_info->pdBlock;
- u16 *pDevHandle = &io_info->devHandle;
+ __le16 *pDevHandle = &io_info->devHandle;
u32 logArm, rowMod, armQ, arm;
+ struct fusion_context *fusion;
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
- instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
- do_invader = 1;
+ fusion = instance->ctrl_context;
/*Get row and span from io_info for Uneven Span IO.*/
row = io_info->start_row;
@@ -769,9 +775,10 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
if (pd != MR_PD_INVALID)
*pDevHandle = MR_PdDevHandleGet(pd, map);
else {
- *pDevHandle = MR_PD_INVALID;
+ *pDevHandle = cpu_to_le16(MR_PD_INVALID);
if ((raid->level >= 5) &&
- (!do_invader || (do_invader &&
+ ((fusion->adapter_type == THUNDERBOLT_SERIES) ||
+ ((fusion->adapter_type == INVADER_SERIES) &&
(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
else if (raid->level == 1) {
@@ -815,13 +822,12 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
u8 physArm, span;
u64 row;
u8 retval = TRUE;
- u8 do_invader = 0;
u64 *pdBlock = &io_info->pdBlock;
- u16 *pDevHandle = &io_info->devHandle;
+ __le16 *pDevHandle = &io_info->devHandle;
+ struct fusion_context *fusion;
+
+ fusion = instance->ctrl_context;
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
- instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
- do_invader = 1;
row = mega_div64_32(stripRow, raid->rowDataSize);
@@ -864,9 +870,11 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
/* Get dev handle from Pd. */
*pDevHandle = MR_PdDevHandleGet(pd, map);
else {
- *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
+ /* set dev handle as invalid. */
+ *pDevHandle = cpu_to_le16(MR_PD_INVALID);
if ((raid->level >= 5) &&
- (!do_invader || (do_invader &&
+ ((fusion->adapter_type == THUNDERBOLT_SERIES) ||
+ ((fusion->adapter_type == INVADER_SERIES) &&
(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
else if (raid->level == 1) {
@@ -900,6 +908,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
struct RAID_CONTEXT *pRAID_Context,
struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN)
{
+ struct fusion_context *fusion;
struct MR_LD_RAID *raid;
u32 ld, stripSize, stripe_mask;
u64 endLba, endStrip, endRow, start_row, start_strip;
@@ -920,6 +929,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
isRead = io_info->isRead;
io_info->IoforUnevenSpan = 0;
io_info->start_span = SPAN_INVALID;
+ fusion = instance->ctrl_context;
ld = MR_TargetIdToLdGet(ldTgtId, map);
raid = MR_LdRaidGet(ld, map);
@@ -1083,8 +1093,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
cpu_to_le16(raid->fpIoTimeoutForLd ?
raid->fpIoTimeoutForLd :
map->raidMap.fpPdIoTimeoutSec);
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+ if (fusion->adapter_type == INVADER_SERIES)
pRAID_Context->regLockFlags = (isRead) ?
raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
else
@@ -1109,7 +1118,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
ref_in_start_stripe, io_info,
pRAID_Context, map);
/* If IO on an invalid Pd, then FP is not possible.*/
- if (io_info->devHandle == MR_PD_INVALID)
+ if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID))
io_info->fpOkForIo = FALSE;
return retval;
} else if (isRead) {
@@ -1189,10 +1198,6 @@ void mr_update_span_set(struct MR_DRV_RAID_MAP_ALL *map,
span_row_width +=
MR_LdSpanPtrGet
(ld, count, map)->spanRowDataSize;
- printk(KERN_INFO "megasas:"
- "span %x rowDataSize %x\n",
- count, MR_LdSpanPtrGet
- (ld, count, map)->spanRowDataSize);
}
}
@@ -1341,11 +1346,11 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
return io_info->pd_after_lb;
}
-u16 get_updated_dev_handle(struct megasas_instance *instance,
+__le16 get_updated_dev_handle(struct megasas_instance *instance,
struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *io_info)
{
u8 arm_pd;
- u16 devHandle;
+ __le16 devHandle;
struct fusion_context *fusion;
struct MR_DRV_RAID_MAP_ALL *drv_map;
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c b/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 5a0800d19..8d630a552 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -53,10 +53,12 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_dbg.h>
+#include <linux/dmi.h>
#include "megaraid_sas_fusion.h"
#include "megaraid_sas.h"
+
extern void megasas_free_cmds(struct megasas_instance *instance);
extern struct megasas_cmd *megasas_get_cmd(struct megasas_instance
*instance);
@@ -156,28 +158,15 @@ megasas_clear_intr_fusion(struct megasas_register_set __iomem *regs)
* megasas_get_cmd_fusion - Get a command from the free pool
* @instance: Adapter soft state
*
- * Returns a free command from the pool
+ * Returns a blk_tag indexed mpt frame
*/
-struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
- *instance)
+inline struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
+ *instance, u32 blk_tag)
{
- unsigned long flags;
- struct fusion_context *fusion =
- (struct fusion_context *)instance->ctrl_context;
- struct megasas_cmd_fusion *cmd = NULL;
-
- spin_lock_irqsave(&fusion->mpt_pool_lock, flags);
-
- if (!list_empty(&fusion->cmd_pool)) {
- cmd = list_entry((&fusion->cmd_pool)->next,
- struct megasas_cmd_fusion, list);
- list_del_init(&cmd->list);
- } else {
- printk(KERN_ERR "megasas: Command pool (fusion) empty!\n");
- }
+ struct fusion_context *fusion;
- spin_unlock_irqrestore(&fusion->mpt_pool_lock, flags);
- return cmd;
+ fusion = instance->ctrl_context;
+ return fusion->cmd_list[blk_tag];
}
/**
@@ -188,47 +177,35 @@ struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
struct megasas_cmd_fusion *cmd)
{
- unsigned long flags;
- struct fusion_context *fusion =
- (struct fusion_context *)instance->ctrl_context;
-
- spin_lock_irqsave(&fusion->mpt_pool_lock, flags);
-
cmd->scmd = NULL;
- cmd->sync_cmd_idx = (u32)ULONG_MAX;
memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
- list_add(&cmd->list, (&fusion->cmd_pool)->next);
-
- spin_unlock_irqrestore(&fusion->mpt_pool_lock, flags);
}
/**
- * megasas_return_mfi_mpt_pthr - Return a mfi and mpt to free command pool
- * @instance: Adapter soft state
- * @cmd_mfi: MFI Command packet to be returned to free command pool
- * @cmd_mpt: MPT Command packet to be returned to free command pool
+ * megasas_fire_cmd_fusion - Sends command to the FW
*/
-inline void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
- struct megasas_cmd *cmd_mfi,
- struct megasas_cmd_fusion *cmd_fusion)
+static void
+megasas_fire_cmd_fusion(struct megasas_instance *instance,
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc)
{
+#if defined(writeq) && defined(CONFIG_64BIT)
+ u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
+ le32_to_cpu(req_desc->u.low));
+
+ writeq(req_data, &instance->reg_set->inbound_low_queue_port);
+#else
unsigned long flags;
- /*
- * TO DO: optimize this code and use only one lock instead of two
- * locks being used currently- mpt_pool_lock is acquired
- * inside mfi_pool_lock
- */
- spin_lock_irqsave(&instance->mfi_pool_lock, flags);
- megasas_return_cmd_fusion(instance, cmd_fusion);
- if (atomic_read(&cmd_mfi->mfi_mpt_pthr) != MFI_MPT_ATTACHED)
- dev_err(&instance->pdev->dev, "Possible bug from %s %d\n",
- __func__, __LINE__);
- atomic_set(&cmd_mfi->mfi_mpt_pthr, MFI_MPT_DETACHED);
- __megasas_return_cmd(instance, cmd_mfi);
- spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
+ spin_lock_irqsave(&instance->hba_lock, flags);
+ writel(le32_to_cpu(req_desc->u.low),
+ &instance->reg_set->inbound_low_queue_port);
+ writel(le32_to_cpu(req_desc->u.high),
+ &instance->reg_set->inbound_high_queue_port);
+ spin_unlock_irqrestore(&instance->hba_lock, flags);
+#endif
}
+
/**
* megasas_teardown_frame_pool_fusion - Destroy the cmd frame DMA pool
* @instance: Adapter soft state
@@ -244,7 +221,7 @@ static void megasas_teardown_frame_pool_fusion(
struct megasas_cmd_fusion *cmd;
if (!fusion->sg_dma_pool || !fusion->sense_dma_pool) {
- printk(KERN_ERR "megasas: dma pool is null. SG Pool %p, "
+ dev_err(&instance->pdev->dev, "dma pool is null. SG Pool %p, "
"sense pool : %p\n", fusion->sg_dma_pool,
fusion->sense_dma_pool);
return;
@@ -326,7 +303,6 @@ megasas_free_cmds_fusion(struct megasas_instance *instance)
kfree(fusion->cmd_list);
fusion->cmd_list = NULL;
- INIT_LIST_HEAD(&fusion->cmd_pool);
}
/**
@@ -340,33 +316,28 @@ static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
u32 max_cmd;
struct fusion_context *fusion;
struct megasas_cmd_fusion *cmd;
- u32 total_sz_chain_frame;
fusion = instance->ctrl_context;
max_cmd = instance->max_fw_cmds;
- total_sz_chain_frame = MEGASAS_MAX_SZ_CHAIN_FRAME;
/*
* Use DMA pool facility provided by PCI layer
*/
- fusion->sg_dma_pool = pci_pool_create("megasas sg pool fusion",
- instance->pdev,
- total_sz_chain_frame, 4,
- 0);
+ fusion->sg_dma_pool = pci_pool_create("sg_pool_fusion", instance->pdev,
+ instance->max_chain_frame_sz,
+ 4, 0);
if (!fusion->sg_dma_pool) {
- printk(KERN_DEBUG "megasas: failed to setup request pool "
- "fusion\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup request pool fusion\n");
return -ENOMEM;
}
- fusion->sense_dma_pool = pci_pool_create("megasas sense pool fusion",
+ fusion->sense_dma_pool = pci_pool_create("sense pool fusion",
instance->pdev,
SCSI_SENSE_BUFFERSIZE, 64, 0);
if (!fusion->sense_dma_pool) {
- printk(KERN_DEBUG "megasas: failed to setup sense pool "
- "fusion\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup sense pool fusion\n");
pci_pool_destroy(fusion->sg_dma_pool);
fusion->sg_dma_pool = NULL;
return -ENOMEM;
@@ -390,7 +361,7 @@ static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
* whatever has been allocated
*/
if (!cmd->sg_frame || !cmd->sense) {
- printk(KERN_DEBUG "megasas: pci_pool_alloc failed\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "pci_pool_alloc failed\n");
megasas_teardown_frame_pool_fusion(instance);
return -ENOMEM;
}
@@ -436,7 +407,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
&fusion->req_frames_desc_phys, GFP_KERNEL);
if (!fusion->req_frames_desc) {
- printk(KERN_ERR "megasas; Could not allocate memory for "
+ dev_err(&instance->pdev->dev, "Could not allocate memory for "
"request_frames\n");
goto fail_req_desc;
}
@@ -447,7 +418,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
fusion->reply_alloc_sz * count, 16, 0);
if (!fusion->reply_frames_desc_pool) {
- printk(KERN_ERR "megasas; Could not allocate memory for "
+ dev_err(&instance->pdev->dev, "Could not allocate memory for "
"reply_frame pool\n");
goto fail_reply_desc;
}
@@ -456,7 +427,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
pci_pool_alloc(fusion->reply_frames_desc_pool, GFP_KERNEL,
&fusion->reply_frames_desc_phys);
if (!fusion->reply_frames_desc) {
- printk(KERN_ERR "megasas; Could not allocate memory for "
+ dev_err(&instance->pdev->dev, "Could not allocate memory for "
"reply_frame pool\n");
pci_pool_destroy(fusion->reply_frames_desc_pool);
goto fail_reply_desc;
@@ -464,7 +435,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
reply_desc = fusion->reply_frames_desc;
for (i = 0; i < fusion->reply_q_depth * count; i++, reply_desc++)
- reply_desc->Words = ULLONG_MAX;
+ reply_desc->Words = cpu_to_le64(ULLONG_MAX);
io_frames_sz = fusion->io_frames_alloc_sz;
@@ -473,7 +444,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
fusion->io_frames_alloc_sz, 16, 0);
if (!fusion->io_request_frames_pool) {
- printk(KERN_ERR "megasas: Could not allocate memory for "
+ dev_err(&instance->pdev->dev, "Could not allocate memory for "
"io_request_frame pool\n");
goto fail_io_frames;
}
@@ -482,7 +453,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
pci_pool_alloc(fusion->io_request_frames_pool, GFP_KERNEL,
&fusion->io_request_frames_phys);
if (!fusion->io_request_frames) {
- printk(KERN_ERR "megasas: Could not allocate memory for "
+ dev_err(&instance->pdev->dev, "Could not allocate memory for "
"io_request_frames frames\n");
pci_pool_destroy(fusion->io_request_frames_pool);
goto fail_io_frames;
@@ -497,7 +468,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
* max_cmd, GFP_KERNEL);
if (!fusion->cmd_list) {
- printk(KERN_DEBUG "megasas: out of memory. Could not alloc "
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "out of memory. Could not alloc "
"memory for cmd_list_fusion\n");
goto fail_cmd_list;
}
@@ -507,7 +478,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
fusion->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd_fusion),
GFP_KERNEL);
if (!fusion->cmd_list[i]) {
- printk(KERN_ERR "Could not alloc cmd list fusion\n");
+ dev_err(&instance->pdev->dev, "Could not alloc cmd list fusion\n");
for (j = 0; j < i; j++)
kfree(fusion->cmd_list[j]);
@@ -535,7 +506,9 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
memset(cmd, 0, sizeof(struct megasas_cmd_fusion));
cmd->index = i + 1;
cmd->scmd = NULL;
- cmd->sync_cmd_idx = (u32)ULONG_MAX; /* Set to Invalid */
+ cmd->sync_cmd_idx = (i >= instance->max_scsi_cmds) ?
+ (i - instance->max_scsi_cmds) :
+ (u32)ULONG_MAX; /* Set to Invalid */
cmd->instance = instance;
cmd->io_request =
(struct MPI2_RAID_SCSI_IO_REQUEST *)
@@ -543,15 +516,13 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
memset(cmd->io_request, 0,
sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
cmd->io_request_phys_addr = io_req_base_phys + offset;
-
- list_add_tail(&cmd->list, &fusion->cmd_pool);
}
/*
* Create a frame pool and assign one frame to each cmd
*/
if (megasas_create_frame_pool_fusion(instance)) {
- printk(KERN_DEBUG "megasas: Error creating frame DMA pool\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error creating frame DMA pool\n");
megasas_free_cmds_fusion(instance);
goto fail_req_desc;
}
@@ -605,14 +576,11 @@ wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
msleep(20);
}
- if (frame_hdr->cmd_status == 0xff) {
- if (fusion)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
+ if (frame_hdr->cmd_status == 0xff)
return -ETIME;
- }
- return 0;
+ return (frame_hdr->cmd_status == MFI_STAT_OK) ?
+ 0 : 1;
}
/**
@@ -633,13 +601,15 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
union MEGASAS_REQUEST_DESCRIPTOR_UNION req_desc;
int i;
struct megasas_header *frame_hdr;
+ const char *sys_info;
+ MFI_CAPABILITIES *drv_ops;
fusion = instance->ctrl_context;
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_ERR "Could not allocate cmd for INIT Frame\n");
+ dev_err(&instance->pdev->dev, "Could not allocate cmd for INIT Frame\n");
ret = 1;
goto fail_get_cmd;
}
@@ -650,7 +620,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
&ioc_init_handle, GFP_KERNEL);
if (!IOCInitMessage) {
- printk(KERN_ERR "Could not allocate memory for "
+ dev_err(&instance->pdev->dev, "Could not allocate memory for "
"IOCInitMessage\n");
ret = 1;
goto fail_fw_init;
@@ -673,28 +643,41 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
frame_hdr = &cmd->frame->hdr;
frame_hdr->cmd_status = 0xFF;
- frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
+ frame_hdr->flags = cpu_to_le16(
+ le16_to_cpu(frame_hdr->flags) |
+ MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
init_frame->cmd = MFI_CMD_INIT;
init_frame->cmd_status = 0xFF;
+ drv_ops = (MFI_CAPABILITIES *) &(init_frame->driver_operations);
+
/* driver support Extended MSIX */
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
- init_frame->driver_operations.
- mfi_capabilities.support_additional_msix = 1;
+ if (fusion->adapter_type == INVADER_SERIES)
+ drv_ops->mfi_capabilities.support_additional_msix = 1;
/* driver supports HA / Remote LUN over Fast Path interface */
- init_frame->driver_operations.mfi_capabilities.support_fp_remote_lun
- = 1;
- init_frame->driver_operations.mfi_capabilities.support_max_255lds
- = 1;
- init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb
- = 1;
- init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw
- = 1;
+ drv_ops->mfi_capabilities.support_fp_remote_lun = 1;
+
+ drv_ops->mfi_capabilities.support_max_255lds = 1;
+ drv_ops->mfi_capabilities.support_ndrive_r1_lb = 1;
+ drv_ops->mfi_capabilities.security_protocol_cmds_fw = 1;
+
+ if (instance->max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN)
+ drv_ops->mfi_capabilities.support_ext_io_size = 1;
+
/* Convert capability to LE32 */
cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
+ sys_info = dmi_get_system_info(DMI_PRODUCT_UUID);
+ if (instance->system_info_buf && sys_info) {
+ memcpy(instance->system_info_buf->systemId, sys_info,
+ strlen(sys_info) > 64 ? 64 : strlen(sys_info));
+ instance->system_info_buf->systemIdLength =
+ strlen(sys_info) > 64 ? 64 : strlen(sys_info);
+ init_frame->system_info_lo = instance->system_info_h;
+ init_frame->system_info_hi = 0;
+ }
+
init_frame->queue_info_new_phys_addr_hi =
cpu_to_le32(upper_32_bits(ioc_init_handle));
init_frame->queue_info_new_phys_addr_lo =
@@ -719,8 +702,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
break;
}
- instance->instancet->fire_cmd(instance, req_desc.u.low,
- req_desc.u.high, instance->reg_set);
+ megasas_fire_cmd_fusion(instance, &req_desc);
wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS);
@@ -729,7 +711,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
ret = 1;
goto fail_fw_init;
}
- printk(KERN_ERR "megasas:IOC Init cmd success\n");
+ dev_err(&instance->pdev->dev, "Init cmd success\n");
ret = 0;
@@ -743,6 +725,83 @@ fail_get_cmd:
return ret;
}
+/**
+ * megasas_sync_pd_seq_num - JBOD SEQ MAP
+ * @instance: Adapter soft state
+ * @pend: set to 1, if it is pended jbod map.
+ *
+ * Issue Jbod map to the firmware. If it is pended command,
+ * issue command and return. If it is first instance of jbod map
+ * issue and receive command.
+ */
+int
+megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) {
+ int ret = 0;
+ u32 pd_seq_map_sz;
+ struct megasas_cmd *cmd;
+ struct megasas_dcmd_frame *dcmd;
+ struct fusion_context *fusion = instance->ctrl_context;
+ struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
+ dma_addr_t pd_seq_h;
+
+ pd_sync = (void *)fusion->pd_seq_sync[(instance->pd_seq_map_id & 1)];
+ pd_seq_h = fusion->pd_seq_phys[(instance->pd_seq_map_id & 1)];
+ pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
+ (sizeof(struct MR_PD_CFG_SEQ) *
+ (MAX_PHYSICAL_DEVICES - 1));
+
+ cmd = megasas_get_cmd(instance);
+ if (!cmd) {
+ dev_err(&instance->pdev->dev,
+ "Could not get mfi cmd. Fail from %s %d\n",
+ __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ dcmd = &cmd->frame->dcmd;
+
+ memset(pd_sync, 0, pd_seq_map_sz);
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0xFF;
+ dcmd->sge_count = 1;
+ dcmd->timeout = 0;
+ dcmd->pad_0 = 0;
+ dcmd->data_xfer_len = cpu_to_le32(pd_seq_map_sz);
+ dcmd->opcode = cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO);
+ dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(pd_seq_h);
+ dcmd->sgl.sge32[0].length = cpu_to_le32(pd_seq_map_sz);
+
+ if (pend) {
+ dcmd->mbox.b[0] = MEGASAS_DCMD_MBOX_PEND_FLAG;
+ dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_WRITE);
+ instance->jbod_seq_cmd = cmd;
+ instance->instancet->issue_dcmd(instance, cmd);
+ return 0;
+ }
+
+ dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+
+ /* Below code is only for non pended DCMD */
+ if (instance->ctrl_context && !instance->mask_interrupts)
+ ret = megasas_issue_blocked_cmd(instance, cmd, 60);
+ else
+ ret = megasas_issue_polled(instance, cmd);
+
+ if (le32_to_cpu(pd_sync->count) > MAX_PHYSICAL_DEVICES) {
+ dev_warn(&instance->pdev->dev,
+ "driver supports max %d JBOD, but FW reports %d\n",
+ MAX_PHYSICAL_DEVICES, le32_to_cpu(pd_sync->count));
+ ret = -EINVAL;
+ }
+
+ if (!ret)
+ instance->pd_seq_map_id++;
+
+ megasas_return_cmd(instance, cmd);
+ return ret;
+}
+
/*
* megasas_get_ld_map_info - Returns FW's ld_map structure
* @instance: Adapter soft state
@@ -772,7 +831,7 @@ megasas_get_ld_map_info(struct megasas_instance *instance)
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas: Failed to get cmd for map info.\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get cmd for map info\n");
return -ENOMEM;
}
@@ -791,7 +850,7 @@ megasas_get_ld_map_info(struct megasas_instance *instance)
ci_h = fusion->ld_map_phys[(instance->map_id & 1)];
if (!ci) {
- printk(KERN_DEBUG "Failed to alloc mem for ld_map_info\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc mem for ld_map_info\n");
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
@@ -820,11 +879,7 @@ megasas_get_ld_map_info(struct megasas_instance *instance)
else
ret = megasas_issue_polled(instance, cmd);
- if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
- megasas_return_mfi_mpt_pthr(instance, cmd,
- cmd->mpt_pthr_cmd_blocked);
- else
- megasas_return_cmd(instance, cmd);
+ megasas_return_cmd(instance, cmd);
return ret;
}
@@ -870,8 +925,7 @@ megasas_sync_map_info(struct megasas_instance *instance)
cmd = megasas_get_cmd(instance);
if (!cmd) {
- printk(KERN_DEBUG "megasas: Failed to get cmd for sync"
- "info.\n");
+ dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get cmd for sync info\n");
return -ENOMEM;
}
@@ -983,6 +1037,18 @@ megasas_display_intel_branding(struct megasas_instance *instance)
break;
}
break;
+ case PCI_DEVICE_ID_LSI_CUTLASS_52:
+ case PCI_DEVICE_ID_LSI_CUTLASS_53:
+ switch (instance->pdev->subsystem_device) {
+ case MEGARAID_INTEL_RMS3BC160_SSDID:
+ dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+ instance->host->host_no,
+ MEGARAID_INTEL_RMS3BC160_BRANDING);
+ break;
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -999,7 +1065,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
{
struct megasas_register_set __iomem *reg_set;
struct fusion_context *fusion;
- u32 max_cmd;
+ u32 max_cmd, scratch_pad_2;
int i = 0, count;
fusion = instance->ctrl_context;
@@ -1038,15 +1104,40 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
(MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE *
(max_cmd + 1)); /* Extra 1 for SMID 0 */
+ scratch_pad_2 = readl(&instance->reg_set->outbound_scratch_pad_2);
+ /* If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set,
+ * Firmware support extended IO chain frame which is 4 times more than
+ * legacy Firmware.
+ * Legacy Firmware - Frame size is (8 * 128) = 1K
+ * 1M IO Firmware - Frame size is (8 * 128 * 4) = 4K
+ */
+ if (scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK)
+ instance->max_chain_frame_sz =
+ ((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >>
+ MEGASAS_MAX_CHAIN_SHIFT) * MEGASAS_1MB_IO;
+ else
+ instance->max_chain_frame_sz =
+ ((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >>
+ MEGASAS_MAX_CHAIN_SHIFT) * MEGASAS_256K_IO;
+
+ if (instance->max_chain_frame_sz < MEGASAS_CHAIN_FRAME_SZ_MIN) {
+ dev_warn(&instance->pdev->dev, "frame size %d invalid, fall back to legacy max frame size %d\n",
+ instance->max_chain_frame_sz,
+ MEGASAS_CHAIN_FRAME_SZ_MIN);
+ instance->max_chain_frame_sz = MEGASAS_CHAIN_FRAME_SZ_MIN;
+ }
+
fusion->max_sge_in_main_msg =
- (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
- offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
+ (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE
+ - offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL))/16;
fusion->max_sge_in_chain =
- MEGASAS_MAX_SZ_CHAIN_FRAME / sizeof(union MPI2_SGE_IO_UNION);
+ instance->max_chain_frame_sz
+ / sizeof(union MPI2_SGE_IO_UNION);
- instance->max_num_sge = rounddown_pow_of_two(
- fusion->max_sge_in_main_msg + fusion->max_sge_in_chain - 2);
+ instance->max_num_sge =
+ rounddown_pow_of_two(fusion->max_sge_in_main_msg
+ + fusion->max_sge_in_chain - 2);
/* Used for pass thru MFI frame (DCMD) */
fusion->chain_offset_mfi_pthru =
@@ -1061,6 +1152,15 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
fusion->last_reply_idx[i] = 0;
/*
+ * For fusion adapters, 3 commands for IOCTL and 5 commands
+ * for driver's internal DCMDs.
+ */
+ instance->max_scsi_cmds = instance->max_fw_cmds -
+ (MEGASAS_FUSION_INTERNAL_CMDS +
+ MEGASAS_FUSION_IOCTL_CMDS);
+ sema_init(&instance->ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS);
+
+ /*
* Allocate memory for descriptors
* Create a pool of commands
*/
@@ -1107,7 +1207,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
&fusion->ld_map_phys[i],
GFP_KERNEL);
if (!fusion->ld_map[i]) {
- printk(KERN_ERR "megasas: Could not allocate memory "
+ dev_err(&instance->pdev->dev, "Could not allocate memory "
"for map info\n");
goto fail_map_info;
}
@@ -1131,34 +1231,6 @@ fail_alloc_mfi_cmds:
}
/**
- * megasas_fire_cmd_fusion - Sends command to the FW
- * @frame_phys_addr : Physical address of cmd
- * @frame_count : Number of frames for the command
- * @regs : MFI register set
- */
-void
-megasas_fire_cmd_fusion(struct megasas_instance *instance,
- dma_addr_t req_desc_lo,
- u32 req_desc_hi,
- struct megasas_register_set __iomem *regs)
-{
-#if defined(writeq) && defined(CONFIG_64BIT)
- u64 req_data = (((u64)le32_to_cpu(req_desc_hi) << 32) |
- le32_to_cpu(req_desc_lo));
-
- writeq(req_data, &(regs)->inbound_low_queue_port);
-#else
- unsigned long flags;
-
- spin_lock_irqsave(&instance->hba_lock, flags);
-
- writel(le32_to_cpu(req_desc_lo), &(regs)->inbound_low_queue_port);
- writel(le32_to_cpu(req_desc_hi), &(regs)->inbound_high_queue_port);
- spin_unlock_irqrestore(&instance->hba_lock, flags);
-#endif
-}
-
-/**
* map_cmd_status - Maps FW cmd status to OS cmd status
* @cmd : Pointer to cmd
* @status : status of cmd returned by FW
@@ -1200,7 +1272,7 @@ map_cmd_status(struct megasas_cmd_fusion *cmd, u8 status, u8 ext_status)
cmd->scmd->result = DID_IMM_RETRY << 16;
break;
default:
- printk(KERN_DEBUG "megasas: FW status %#x\n", status);
+ dev_printk(KERN_DEBUG, &cmd->instance->pdev->dev, "FW status %#x\n", status);
cmd->scmd->result = DID_ERROR << 16;
break;
}
@@ -1227,8 +1299,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
fusion = instance->ctrl_context;
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+ if (fusion->adapter_type == INVADER_SERIES) {
struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr;
sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
sgl_ptr_end->Flags = 0;
@@ -1245,11 +1316,9 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
sgl_ptr->Length = cpu_to_le32(sg_dma_len(os_sgl));
sgl_ptr->Address = cpu_to_le64(sg_dma_address(os_sgl));
sgl_ptr->Flags = 0;
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+ if (fusion->adapter_type == INVADER_SERIES)
if (i == sge_count - 1)
sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST;
- }
sgl_ptr++;
sg_processed = i + 1;
@@ -1258,10 +1327,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
(sge_count > fusion->max_sge_in_main_msg)) {
struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
- if ((instance->pdev->device ==
- PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FURY)) {
+ if (fusion->adapter_type == INVADER_SERIES) {
if ((le16_to_cpu(cmd->io_request->IoFlags) &
MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)
@@ -1277,10 +1343,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
sg_chain = sgl_ptr;
/* Prepare chain element */
sg_chain->NextChainOffset = 0;
- if ((instance->pdev->device ==
- PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FURY))
+ if (fusion->adapter_type == INVADER_SERIES)
sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT;
else
sg_chain->Flags =
@@ -1291,7 +1354,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
sgl_ptr =
(struct MPI25_IEEE_SGE_CHAIN64 *)cmd->sg_frame;
- memset(sgl_ptr, 0, MEGASAS_MAX_SZ_CHAIN_FRAME);
+ memset(sgl_ptr, 0, instance->max_chain_frame_sz);
}
}
@@ -1497,7 +1560,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
u8 *raidLUN;
- device_id = MEGASAS_DEV_INDEX(instance, scp);
+ device_id = MEGASAS_DEV_INDEX(scp);
fusion = instance->ctrl_context;
@@ -1597,8 +1660,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
<< MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+ if (fusion->adapter_type == INVADER_SERIES) {
if (io_request->RaidContext.regLockFlags ==
REGION_TYPE_UNUSED)
cmd->request_desc->SCSIIO.RequestFlags =
@@ -1621,6 +1683,14 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
cmd->pd_r1_lb = io_info.pd_after_lb;
} else
scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
+
+ if ((raidLUN[0] == 1) &&
+ (local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 1)) {
+ instance->dev_handle = !(instance->dev_handle);
+ io_info.devHandle =
+ local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].devHandle[instance->dev_handle];
+ }
+
cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle;
io_request->DevHandle = io_info.devHandle;
/* populate the LUN field */
@@ -1631,8 +1701,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
cmd->request_desc->SCSIIO.RequestFlags =
(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
<< MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+ if (fusion->adapter_type == INVADER_SERIES) {
if (io_request->RaidContext.regLockFlags ==
REGION_TYPE_UNUSED)
cmd->request_desc->SCSIIO.RequestFlags =
@@ -1650,121 +1719,68 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
}
/**
- * megasas_build_dcdb_fusion - Prepares IOs to devices
+ * megasas_build_ld_nonrw_fusion - prepares non rw ios for virtual disk
* @instance: Adapter soft state
* @scp: SCSI command
* @cmd: Command to be prepared
*
- * Prepares the io_request frame for non-io cmds
+ * Prepares the io_request frame for non-rw io cmds for vd.
*/
-static void
-megasas_build_dcdb_fusion(struct megasas_instance *instance,
- struct scsi_cmnd *scmd,
- struct megasas_cmd_fusion *cmd)
+static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
+ struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd)
{
u32 device_id;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
u16 pd_index = 0;
- u16 os_timeout_value;
- u16 timeout_limit;
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
struct fusion_context *fusion = instance->ctrl_context;
u8 span, physArm;
- u16 devHandle;
+ __le16 devHandle;
u32 ld, arRef, pd;
struct MR_LD_RAID *raid;
struct RAID_CONTEXT *pRAID_Context;
+ u8 fp_possible = 1;
io_request = cmd->io_request;
- device_id = MEGASAS_DEV_INDEX(instance, scmd);
- pd_index = (scmd->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL)
- +scmd->device->id;
+ device_id = MEGASAS_DEV_INDEX(scmd);
+ pd_index = MEGASAS_PD_INDEX(scmd);
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
-
io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
+ /* get RAID_Context pointer */
+ pRAID_Context = &io_request->RaidContext;
+ /* Check with FW team */
+ pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+ pRAID_Context->regLockRowLBA = 0;
+ pRAID_Context->regLockLength = 0;
- if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS &&
- instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
- if (fusion->fast_path_io)
- io_request->DevHandle =
- local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
- io_request->RaidContext.RAIDFlags =
- MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
- << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
- cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
- cmd->request_desc->SCSIIO.MSIxIndex =
- instance->msix_vectors ?
- raw_smp_processor_id() %
- instance->msix_vectors :
- 0;
- os_timeout_value = scmd->request->timeout / HZ;
-
- if (instance->secure_jbod_support &&
- (megasas_cmd_type(scmd) == NON_READ_WRITE_SYSPDIO)) {
- /* system pd firmware path */
- io_request->Function =
- MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
- cmd->request_desc->SCSIIO.RequestFlags =
- (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
- MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
- io_request->RaidContext.timeoutValue =
- cpu_to_le16(os_timeout_value);
- } else {
- /* system pd Fast Path */
- io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
- io_request->RaidContext.regLockFlags = 0;
- io_request->RaidContext.regLockRowLBA = 0;
- io_request->RaidContext.regLockLength = 0;
- timeout_limit = (scmd->device->type == TYPE_DISK) ?
- 255 : 0xFFFF;
- io_request->RaidContext.timeoutValue =
- cpu_to_le16((os_timeout_value > timeout_limit) ?
- timeout_limit : os_timeout_value);
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
- io_request->IoFlags |=
- cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
-
- cmd->request_desc->SCSIIO.RequestFlags =
- (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
- MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
- }
- } else {
- if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS)
- goto NonFastPath;
-
- /*
- * For older firmware, Driver should not access ldTgtIdToLd
- * beyond index 127 and for Extended VD firmware, ldTgtIdToLd
- * should not go beyond 255.
- */
-
- if ((!fusion->fast_path_io) ||
- (device_id >= instance->fw_supported_vd_count))
- goto NonFastPath;
+ if (fusion->fast_path_io && (
+ device_id < instance->fw_supported_vd_count)) {
ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
-
if (ld >= instance->fw_supported_vd_count)
- goto NonFastPath;
+ fp_possible = 0;
raid = MR_LdRaidGet(ld, local_map_ptr);
-
- /* check if this LD is FP capable */
if (!(raid->capability.fpNonRWCapable))
- /* not FP capable, send as non-FP */
- goto NonFastPath;
+ fp_possible = 0;
+ } else
+ fp_possible = 0;
- /* get RAID_Context pointer */
- pRAID_Context = &io_request->RaidContext;
+ if (!fp_possible) {
+ io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
+ io_request->DevHandle = cpu_to_le16(device_id);
+ io_request->LUN[1] = scmd->device->lun;
+ pRAID_Context->timeoutValue =
+ cpu_to_le16 (scmd->request->timeout / HZ);
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ } else {
/* set RAID context values */
- pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
- pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
- pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
- pRAID_Context->regLockRowLBA = 0;
- pRAID_Context->regLockLength = 0;
- pRAID_Context->configSeqNum = raid->seqNum;
+ pRAID_Context->configSeqNum = raid->seqNum;
+ pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
+ pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
/* get the DevHandle for the PD (since this is
fpNonRWCapable, this is a single disk RAID0) */
@@ -1776,7 +1792,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
/* build request descriptor */
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
- MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
cmd->request_desc->SCSIIO.DevHandle = devHandle;
/* populate the LUN field */
@@ -1785,18 +1801,105 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
/* build the raidScsiIO structure */
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
io_request->DevHandle = devHandle;
+ }
+}
- return;
+/**
+ * megasas_build_syspd_fusion - prepares rw/non-rw ios for syspd
+ * @instance: Adapter soft state
+ * @scp: SCSI command
+ * @cmd: Command to be prepared
+ * @fp_possible: parameter to detect fast path or firmware path io.
+ *
+ * Prepares the io_request frame for rw/non-rw io cmds for syspds
+ */
+static void
+megasas_build_syspd_fusion(struct megasas_instance *instance,
+ struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, u8 fp_possible)
+{
+ u32 device_id;
+ struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
+ u16 pd_index = 0;
+ u16 os_timeout_value;
+ u16 timeout_limit;
+ struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
+ struct RAID_CONTEXT *pRAID_Context;
+ struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
+ struct fusion_context *fusion = instance->ctrl_context;
+ pd_sync = (void *)fusion->pd_seq_sync[(instance->pd_seq_map_id - 1) & 1];
+
+ device_id = MEGASAS_DEV_INDEX(scmd);
+ pd_index = MEGASAS_PD_INDEX(scmd);
+ os_timeout_value = scmd->request->timeout / HZ;
-NonFastPath:
+ io_request = cmd->io_request;
+ /* get RAID_Context pointer */
+ pRAID_Context = &io_request->RaidContext;
+ pRAID_Context->regLockFlags = 0;
+ pRAID_Context->regLockRowLBA = 0;
+ pRAID_Context->regLockLength = 0;
+ io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
+ io_request->LUN[1] = scmd->device->lun;
+ pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
+ << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
+
+ /* If FW supports PD sequence number */
+ if (instance->use_seqnum_jbod_fp &&
+ instance->pd_list[pd_index].driveType == TYPE_DISK) {
+ /* TgtId must be incremented by 255 as jbod seq number is index
+ * below raid map
+ */
+ pRAID_Context->VirtualDiskTgtId =
+ cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1));
+ pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum;
+ io_request->DevHandle = pd_sync->seq[pd_index].devHandle;
+ pRAID_Context->regLockFlags |=
+ (MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
+ } else if (fusion->fast_path_io) {
+ pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+ pRAID_Context->configSeqNum = 0;
+ local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+ io_request->DevHandle =
+ local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+ } else {
+ /* Want to send all IO via FW path */
+ pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+ pRAID_Context->configSeqNum = 0;
+ io_request->DevHandle = cpu_to_le16(0xFFFF);
+ }
+
+ cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
+ cmd->request_desc->SCSIIO.MSIxIndex =
+ instance->msix_vectors ?
+ (raw_smp_processor_id() % instance->msix_vectors) : 0;
+
+
+ if (!fp_possible) {
+ /* system pd firmware path */
io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
- io_request->DevHandle = cpu_to_le16(device_id);
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
- MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
+ pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+ } else {
+ /* system pd Fast Path */
+ io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
+ timeout_limit = (scmd->device->type == TYPE_DISK) ?
+ 255 : 0xFFFF;
+ pRAID_Context->timeoutValue =
+ cpu_to_le16((os_timeout_value > timeout_limit) ?
+ timeout_limit : os_timeout_value);
+ if (fusion->adapter_type == INVADER_SERIES) {
+ pRAID_Context->Type = MPI2_TYPE_CUDA;
+ pRAID_Context->nseg = 0x1;
+ io_request->IoFlags |=
+ cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
+ }
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+ MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
}
- io_request->RaidContext.VirtualDiskTgtId = cpu_to_le16(device_id);
- int_to_scsilun(scmd->device->lun, (struct scsi_lun *)io_request->LUN);
}
/**
@@ -1813,11 +1916,10 @@ megasas_build_io_fusion(struct megasas_instance *instance,
struct scsi_cmnd *scp,
struct megasas_cmd_fusion *cmd)
{
- u32 device_id, sge_count;
+ u16 sge_count;
+ u8 cmd_type;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
- device_id = MEGASAS_DEV_INDEX(instance, scp);
-
/* Zero out some fields so they don't get reused */
memset(io_request->LUN, 0x0, 8);
io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
@@ -1837,10 +1939,24 @@ megasas_build_io_fusion(struct megasas_instance *instance,
*/
io_request->IoFlags = cpu_to_le16(scp->cmd_len);
- if (megasas_cmd_type(scp) == READ_WRITE_LDIO)
+ switch (cmd_type = megasas_cmd_type(scp)) {
+ case READ_WRITE_LDIO:
megasas_build_ldio_fusion(instance, scp, cmd);
- else
- megasas_build_dcdb_fusion(instance, scp, cmd);
+ break;
+ case NON_READ_WRITE_LDIO:
+ megasas_build_ld_nonrw_fusion(instance, scp, cmd);
+ break;
+ case READ_WRITE_SYSPDIO:
+ case NON_READ_WRITE_SYSPDIO:
+ if (instance->secure_jbod_support &&
+ (cmd_type == NON_READ_WRITE_SYSPDIO))
+ megasas_build_syspd_fusion(instance, scp, cmd, 0);
+ else
+ megasas_build_syspd_fusion(instance, scp, cmd, 1);
+ break;
+ default:
+ break;
+ }
/*
* Construct SGL
@@ -1852,13 +1968,17 @@ megasas_build_io_fusion(struct megasas_instance *instance,
&io_request->SGL, cmd);
if (sge_count > instance->max_num_sge) {
- printk(KERN_ERR "megasas: Error. sge_count (0x%x) exceeds "
+ dev_err(&instance->pdev->dev, "Error. sge_count (0x%x) exceeds "
"max (0x%x) allowed\n", sge_count,
instance->max_num_sge);
return 1;
}
+ /* numSGE store lower 8 bit of sge_count.
+ * numSGEExt store higher 8 bit of sge_count
+ */
io_request->RaidContext.numSGE = sge_count;
+ io_request->RaidContext.numSGEExt = (u8)(sge_count >> 8);
io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
@@ -1886,7 +2006,7 @@ megasas_get_request_descriptor(struct megasas_instance *instance, u16 index)
struct fusion_context *fusion;
if (index >= instance->max_fw_cmds) {
- printk(KERN_ERR "megasas: Invalid SMID (0x%x)request for "
+ dev_err(&instance->pdev->dev, "Invalid SMID (0x%x)request for "
"descriptor for scsi%d\n", index,
instance->host->host_no);
return NULL;
@@ -1915,9 +2035,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
fusion = instance->ctrl_context;
- cmd = megasas_get_cmd_fusion(instance);
- if (!cmd)
- return SCSI_MLQUEUE_HOST_BUSY;
+ cmd = megasas_get_cmd_fusion(instance, scmd->request->tag);
index = cmd->index;
@@ -1930,7 +2048,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
if (megasas_build_io_fusion(instance, scmd, cmd)) {
megasas_return_cmd_fusion(instance, cmd);
- printk(KERN_ERR "megasas: Error building command.\n");
+ dev_err(&instance->pdev->dev, "Error building command\n");
cmd->request_desc = NULL;
return 1;
}
@@ -1940,7 +2058,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
if (cmd->io_request->ChainOffset != 0 &&
cmd->io_request->ChainOffset != 0xF)
- printk(KERN_ERR "megasas: The chain offset value is not "
+ dev_err(&instance->pdev->dev, "The chain offset value is not "
"correct : %x\n", cmd->io_request->ChainOffset);
/*
@@ -1948,9 +2066,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
*/
atomic_inc(&instance->fw_outstanding);
- instance->instancet->fire_cmd(instance,
- req_desc->u.low, req_desc->u.high,
- instance->reg_set);
+ megasas_fire_cmd_fusion(instance, req_desc);
return 0;
}
@@ -1975,6 +2091,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
union desc_value d_val;
struct LD_LOAD_BALANCE_INFO *lbinfo;
int threshold_reply_count = 0;
+ struct scsi_cmnd *scmd_local = NULL;
fusion = instance->ctrl_context;
@@ -1998,7 +2115,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
num_completed = 0;
- while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) {
+ while (d_val.u.low != cpu_to_le32(UINT_MAX) &&
+ d_val.u.high != cpu_to_le32(UINT_MAX)) {
smid = le16_to_cpu(reply_desc->SMID);
cmd_fusion = fusion->cmd_list[smid - 1];
@@ -2010,14 +2128,14 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
if (cmd_fusion->scmd)
cmd_fusion->scmd->SCp.ptr = NULL;
+ scmd_local = cmd_fusion->scmd;
status = scsi_io_req->RaidContext.status;
extStatus = scsi_io_req->RaidContext.exStatus;
switch (scsi_io_req->Function) {
case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
/* Update load balancing info */
- device_id = MEGASAS_DEV_INDEX(instance,
- cmd_fusion->scmd);
+ device_id = MEGASAS_DEV_INDEX(scmd_local);
lbinfo = &fusion->load_balance_info[device_id];
if (cmd_fusion->scmd->SCp.Status &
MEGASAS_LOAD_BALANCE_FLAG) {
@@ -2028,36 +2146,32 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
if (reply_descript_type ==
MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
if (megasas_dbg_lvl == 5)
- printk(KERN_ERR "\nmegasas: FAST Path "
+ dev_err(&instance->pdev->dev, "\nFAST Path "
"IO Success\n");
}
/* Fall thru and complete IO */
case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */
/* Map the FW Cmd Status */
map_cmd_status(cmd_fusion, status, extStatus);
- scsi_dma_unmap(cmd_fusion->scmd);
- cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
scsi_io_req->RaidContext.status = 0;
scsi_io_req->RaidContext.exStatus = 0;
megasas_return_cmd_fusion(instance, cmd_fusion);
+ scsi_dma_unmap(scmd_local);
+ scmd_local->scsi_done(scmd_local);
atomic_dec(&instance->fw_outstanding);
break;
case MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST: /*MFI command */
cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
- if (!cmd_mfi->mpt_pthr_cmd_blocked) {
- if (megasas_dbg_lvl == 5)
- dev_info(&instance->pdev->dev,
- "freeing mfi/mpt pass-through "
- "from %s %d\n",
- __func__, __LINE__);
- megasas_return_mfi_mpt_pthr(instance, cmd_mfi,
- cmd_fusion);
- }
-
- megasas_complete_cmd(instance, cmd_mfi, DID_OK);
- cmd_fusion->flags = 0;
+ /* Poll mode. Dummy free.
+ * In case of Interrupt mode, caller has reverse check.
+ */
+ if (cmd_mfi->flags & DRV_DCMD_POLLED_MODE) {
+ cmd_mfi->flags &= ~DRV_DCMD_POLLED_MODE;
+ megasas_return_cmd(instance, cmd_mfi);
+ } else
+ megasas_complete_cmd(instance, cmd_mfi, DID_OK);
break;
}
@@ -2066,7 +2180,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
fusion->reply_q_depth)
fusion->last_reply_idx[MSIxIndex] = 0;
- desc->Words = ULLONG_MAX;
+ desc->Words = cpu_to_le64(ULLONG_MAX);
num_completed++;
threshold_reply_count++;
@@ -2094,10 +2208,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
* pending to be completed
*/
if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) {
- if ((instance->pdev->device ==
- PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device ==
- PCI_DEVICE_ID_LSI_FURY))
+ if (fusion->adapter_type == INVADER_SERIES)
writel(((MSIxIndex & 0x7) << 24) |
fusion->last_reply_idx[MSIxIndex],
instance->reply_post_host_index_addr[MSIxIndex/8]);
@@ -2113,8 +2224,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
return IRQ_NONE;
wmb();
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+ if (fusion->adapter_type == INVADER_SERIES)
writel(((MSIxIndex & 0x7) << 24) |
fusion->last_reply_idx[MSIxIndex],
instance->reply_post_host_index_addr[MSIxIndex/8]);
@@ -2193,7 +2303,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp)
else if (fw_state == MFI_STATE_FAULT)
schedule_work(&instance->work_init);
} else if (fw_state == MFI_STATE_FAULT) {
- printk(KERN_WARNING "megaraid_sas: Iop2SysDoorbellInt"
+ dev_warn(&instance->pdev->dev, "Iop2SysDoorbellInt"
"for scsi%d\n", instance->host->host_no);
schedule_work(&instance->work_init);
}
@@ -2217,27 +2327,14 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
struct megasas_cmd_fusion *cmd;
struct fusion_context *fusion;
struct megasas_header *frame_hdr = &mfi_cmd->frame->hdr;
- u32 opcode;
- cmd = megasas_get_cmd_fusion(instance);
- if (!cmd)
- return 1;
+ fusion = instance->ctrl_context;
+
+ cmd = megasas_get_cmd_fusion(instance,
+ instance->max_scsi_cmds + mfi_cmd->index);
/* Save the smid. To be used for returning the cmd */
mfi_cmd->context.smid = cmd->index;
- cmd->sync_cmd_idx = mfi_cmd->index;
-
- /* Set this only for Blocked commands */
- opcode = le32_to_cpu(mfi_cmd->frame->dcmd.opcode);
- if ((opcode == MR_DCMD_LD_MAP_GET_INFO)
- && (mfi_cmd->frame->dcmd.mbox.b[1] == 1))
- mfi_cmd->is_wait_event = 1;
-
- if (opcode == MR_DCMD_CTRL_EVENT_WAIT)
- mfi_cmd->is_wait_event = 1;
-
- if (mfi_cmd->is_wait_event)
- mfi_cmd->mpt_pthr_cmd_blocked = cmd;
/*
* For cmds where the flag is set, store the flag and check
@@ -2246,13 +2343,11 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
*/
if (frame_hdr->flags & cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE))
- cmd->flags = MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
+ mfi_cmd->flags |= DRV_DCMD_POLLED_MODE;
- fusion = instance->ctrl_context;
io_req = cmd->io_request;
- if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
- (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+ if (fusion->adapter_type == INVADER_SERIES) {
struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end =
(struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL;
sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
@@ -2272,7 +2367,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
- mpi25_ieee_chain->Length = cpu_to_le32(MEGASAS_MAX_SZ_CHAIN_FRAME);
+ mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz);
return 0;
}
@@ -2290,7 +2385,7 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
u16 index;
if (build_mpt_mfi_pass_thru(instance, cmd)) {
- printk(KERN_ERR "Couldn't build MFI pass thru cmd\n");
+ dev_err(&instance->pdev->dev, "Couldn't build MFI pass thru cmd\n");
return NULL;
}
@@ -2324,17 +2419,15 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance,
req_desc = build_mpt_cmd(instance, cmd);
if (!req_desc) {
- printk(KERN_ERR "Couldn't issue MFI pass thru cmd\n");
+ dev_err(&instance->pdev->dev, "Couldn't issue MFI pass thru cmd\n");
return;
}
- atomic_set(&cmd->mfi_mpt_pthr, MFI_MPT_ATTACHED);
- instance->instancet->fire_cmd(instance, req_desc->u.low,
- req_desc->u.high, instance->reg_set);
+ megasas_fire_cmd_fusion(instance, req_desc);
}
/**
* megasas_release_fusion - Reverses the FW initialization
- * @intance: Adapter soft state
+ * @instance: Adapter soft state
*/
void
megasas_release_fusion(struct megasas_instance *instance)
@@ -2410,6 +2503,70 @@ static int
megasas_adp_reset_fusion(struct megasas_instance *instance,
struct megasas_register_set __iomem *regs)
{
+ u32 host_diag, abs_state, retry;
+
+ /* Now try to reset the chip */
+ writel(MPI2_WRSEQ_FLUSH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_1ST_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_2ND_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_3RD_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_4TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_5TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+ writel(MPI2_WRSEQ_6TH_KEY_VALUE, &instance->reg_set->fusion_seq_offset);
+
+ /* Check that the diag write enable (DRWE) bit is on */
+ host_diag = readl(&instance->reg_set->fusion_host_diag);
+ retry = 0;
+ while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
+ msleep(100);
+ host_diag = readl(&instance->reg_set->fusion_host_diag);
+ if (retry++ == 100) {
+ dev_warn(&instance->pdev->dev,
+ "Host diag unlock failed from %s %d\n",
+ __func__, __LINE__);
+ break;
+ }
+ }
+ if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
+ return -1;
+
+ /* Send chip reset command */
+ writel(host_diag | HOST_DIAG_RESET_ADAPTER,
+ &instance->reg_set->fusion_host_diag);
+ msleep(3000);
+
+ /* Make sure reset adapter bit is cleared */
+ host_diag = readl(&instance->reg_set->fusion_host_diag);
+ retry = 0;
+ while (host_diag & HOST_DIAG_RESET_ADAPTER) {
+ msleep(100);
+ host_diag = readl(&instance->reg_set->fusion_host_diag);
+ if (retry++ == 1000) {
+ dev_warn(&instance->pdev->dev,
+ "Diag reset adapter never cleared %s %d\n",
+ __func__, __LINE__);
+ break;
+ }
+ }
+ if (host_diag & HOST_DIAG_RESET_ADAPTER)
+ return -1;
+
+ abs_state = instance->instancet->read_fw_status_reg(instance->reg_set)
+ & MFI_STATE_MASK;
+ retry = 0;
+
+ while ((abs_state <= MFI_STATE_FW_INIT) && (retry++ < 1000)) {
+ msleep(100);
+ abs_state = instance->instancet->
+ read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
+ }
+ if (abs_state <= MFI_STATE_FW_INIT) {
+ dev_warn(&instance->pdev->dev,
+ "fw state < MFI_STATE_FW_INIT, state = 0x%x %s %d\n",
+ abs_state, __func__, __LINE__);
+ return -1;
+ }
+
return 0;
}
@@ -2436,7 +2593,7 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
fw_state = instance->instancet->read_fw_status_reg(
instance->reg_set) & MFI_STATE_MASK;
if (fw_state == MFI_STATE_FAULT) {
- printk(KERN_WARNING "megasas: Found FW in FAULT state,"
+ dev_warn(&instance->pdev->dev, "Found FW in FAULT state,"
" will reset adapter scsi%d.\n",
instance->host->host_no);
retval = 1;
@@ -2459,7 +2616,7 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
hb_seconds_missed++;
if (hb_seconds_missed ==
(MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF/HZ)) {
- printk(KERN_WARNING "megasas: SR-IOV:"
+ dev_warn(&instance->pdev->dev, "SR-IOV:"
" Heartbeat never completed "
" while polling during I/O "
" timeout handling for "
@@ -2477,7 +2634,7 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
goto out;
if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
- printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
+ dev_notice(&instance->pdev->dev, "[%2d]waiting for %d "
"commands to complete for scsi%d\n", i,
outstanding, instance->host->host_no);
megasas_complete_cmd_dpc_fusion(
@@ -2487,7 +2644,7 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
}
if (atomic_read(&instance->fw_outstanding)) {
- printk("megaraid_sas: pending commands remain after waiting, "
+ dev_err(&instance->pdev->dev, "pending commands remain after waiting, "
"will reset adapter scsi%d.\n",
instance->host->host_no);
retval = 1;
@@ -2508,7 +2665,44 @@ void megasas_reset_reply_desc(struct megasas_instance *instance)
fusion->last_reply_idx[i] = 0;
reply_desc = fusion->reply_frames_desc;
for (i = 0 ; i < fusion->reply_q_depth * count; i++, reply_desc++)
- reply_desc->Words = ULLONG_MAX;
+ reply_desc->Words = cpu_to_le64(ULLONG_MAX);
+}
+
+/*
+ * megasas_refire_mgmt_cmd : Re-fire management commands
+ * @instance: Controller's soft instance
+*/
+void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
+{
+ int j;
+ struct megasas_cmd_fusion *cmd_fusion;
+ struct fusion_context *fusion;
+ struct megasas_cmd *cmd_mfi;
+ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
+ u16 smid;
+
+ fusion = instance->ctrl_context;
+
+ /* Re-fire management commands.
+ * Do not traverse complet MPT frame pool. Start from max_scsi_cmds.
+ */
+ for (j = instance->max_scsi_cmds ; j < instance->max_fw_cmds; j++) {
+ cmd_fusion = fusion->cmd_list[j];
+ cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
+ smid = le16_to_cpu(cmd_mfi->context.smid);
+
+ if (!smid)
+ continue;
+ req_desc = megasas_get_request_descriptor
+ (instance, smid - 1);
+ if (req_desc && ((cmd_mfi->frame->dcmd.opcode !=
+ cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)) &&
+ (cmd_mfi->frame->dcmd.opcode !=
+ cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO))))
+ megasas_fire_cmd_fusion(instance, req_desc);
+ else
+ megasas_return_cmd(instance, cmd_mfi);
+ }
}
/* Check for a second path that is currently UP */
@@ -2538,14 +2732,13 @@ out:
/* Core fusion reset function */
int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
{
- int retval = SUCCESS, i, j, retry = 0, convert = 0;
+ int retval = SUCCESS, i, convert = 0;
struct megasas_instance *instance;
struct megasas_cmd_fusion *cmd_fusion;
struct fusion_context *fusion;
- struct megasas_cmd *cmd_mfi;
- union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
- u32 host_diag, abs_state, status_reg, reset_adapter;
+ u32 abs_state, status_reg, reset_adapter;
u32 io_timeout_in_crash_mode = 0;
+ struct scsi_cmnd *scmd_local = NULL;
instance = (struct megasas_instance *)shost->hostdata;
fusion = instance->ctrl_context;
@@ -2553,7 +2746,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
mutex_lock(&instance->reset_mutex);
if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
- printk(KERN_WARNING "megaraid_sas: Hardware critical error, "
+ dev_warn(&instance->pdev->dev, "Hardware critical error, "
"returning FAILED for scsi%d.\n",
instance->host->host_no);
mutex_unlock(&instance->reset_mutex);
@@ -2607,21 +2800,22 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
if (megasas_wait_for_outstanding_fusion(instance, iotimeout,
&convert)) {
instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
- printk(KERN_WARNING "megaraid_sas: resetting fusion "
+ dev_warn(&instance->pdev->dev, "resetting fusion "
"adapter scsi%d.\n", instance->host->host_no);
if (convert)
iotimeout = 0;
/* Now return commands back to the OS */
- for (i = 0 ; i < instance->max_fw_cmds; i++) {
+ for (i = 0 ; i < instance->max_scsi_cmds; i++) {
cmd_fusion = fusion->cmd_list[i];
+ scmd_local = cmd_fusion->scmd;
if (cmd_fusion->scmd) {
- scsi_dma_unmap(cmd_fusion->scmd);
- cmd_fusion->scmd->result =
+ scmd_local->result =
megasas_check_mpio_paths(instance,
- cmd_fusion->scmd);
- cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
+ scmd_local);
megasas_return_cmd_fusion(instance, cmd_fusion);
+ scsi_dma_unmap(scmd_local);
+ scmd_local->scsi_done(scmd_local);
atomic_dec(&instance->fw_outstanding);
}
}
@@ -2633,7 +2827,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
if (instance->disableOnlineCtrlReset ||
(abs_state == MFI_STATE_FAULT && !reset_adapter)) {
/* Reset not supported, kill adapter */
- printk(KERN_WARNING "megaraid_sas: Reset not supported"
+ dev_warn(&instance->pdev->dev, "Reset not supported"
", killing adapter scsi%d.\n",
instance->host->host_no);
megaraid_sas_kill_hba(instance);
@@ -2651,7 +2845,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
instance->hb_host_mem->HB.driverCounter)) {
instance->hb_host_mem->HB.driverCounter =
instance->hb_host_mem->HB.fwCounter;
- printk(KERN_WARNING "megasas: SR-IOV:"
+ dev_warn(&instance->pdev->dev, "SR-IOV:"
"Late FW heartbeat update for "
"scsi%d.\n",
instance->host->host_no);
@@ -2667,8 +2861,8 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
abs_state = status_reg &
MFI_STATE_MASK;
if (abs_state == MFI_STATE_READY) {
- printk(KERN_WARNING "megasas"
- ": SR-IOV: FW was found"
+ dev_warn(&instance->pdev->dev,
+ "SR-IOV: FW was found"
"to be in ready state "
"for scsi%d.\n",
instance->host->host_no);
@@ -2677,7 +2871,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
msleep(20);
}
if (abs_state != MFI_STATE_READY) {
- printk(KERN_WARNING "megasas: SR-IOV: "
+ dev_warn(&instance->pdev->dev, "SR-IOV: "
"FW not in ready state after %d"
" seconds for scsi%d, status_reg = "
"0x%x.\n",
@@ -2696,85 +2890,14 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
/* Now try to reset the chip */
for (i = 0; i < MEGASAS_FUSION_MAX_RESET_TRIES; i++) {
- writel(MPI2_WRSEQ_FLUSH_KEY_VALUE,
- &instance->reg_set->fusion_seq_offset);
- writel(MPI2_WRSEQ_1ST_KEY_VALUE,
- &instance->reg_set->fusion_seq_offset);
- writel(MPI2_WRSEQ_2ND_KEY_VALUE,
- &instance->reg_set->fusion_seq_offset);
- writel(MPI2_WRSEQ_3RD_KEY_VALUE,
- &instance->reg_set->fusion_seq_offset);
- writel(MPI2_WRSEQ_4TH_KEY_VALUE,
- &instance->reg_set->fusion_seq_offset);
- writel(MPI2_WRSEQ_5TH_KEY_VALUE,
- &instance->reg_set->fusion_seq_offset);
- writel(MPI2_WRSEQ_6TH_KEY_VALUE,
- &instance->reg_set->fusion_seq_offset);
-
- /* Check that the diag write enable (DRWE) bit is on */
- host_diag = readl(&instance->reg_set->fusion_host_diag);
- retry = 0;
- while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
- msleep(100);
- host_diag =
- readl(&instance->reg_set->fusion_host_diag);
- if (retry++ == 100) {
- printk(KERN_WARNING "megaraid_sas: "
- "Host diag unlock failed! "
- "for scsi%d\n",
- instance->host->host_no);
- break;
- }
- }
- if (!(host_diag & HOST_DIAG_WRITE_ENABLE))
- continue;
- /* Send chip reset command */
- writel(host_diag | HOST_DIAG_RESET_ADAPTER,
- &instance->reg_set->fusion_host_diag);
- msleep(3000);
-
- /* Make sure reset adapter bit is cleared */
- host_diag = readl(&instance->reg_set->fusion_host_diag);
- retry = 0;
- while (host_diag & HOST_DIAG_RESET_ADAPTER) {
- msleep(100);
- host_diag =
- readl(&instance->reg_set->fusion_host_diag);
- if (retry++ == 1000) {
- printk(KERN_WARNING "megaraid_sas: "
- "Diag reset adapter never "
- "cleared for scsi%d!\n",
- instance->host->host_no);
- break;
- }
- }
- if (host_diag & HOST_DIAG_RESET_ADAPTER)
+ if (instance->instancet->adp_reset
+ (instance, instance->reg_set))
continue;
- abs_state =
- instance->instancet->read_fw_status_reg(
- instance->reg_set) & MFI_STATE_MASK;
- retry = 0;
-
- while ((abs_state <= MFI_STATE_FW_INIT) &&
- (retry++ < 1000)) {
- msleep(100);
- abs_state =
- instance->instancet->read_fw_status_reg(
- instance->reg_set) & MFI_STATE_MASK;
- }
- if (abs_state <= MFI_STATE_FW_INIT) {
- printk(KERN_WARNING "megaraid_sas: firmware "
- "state < MFI_STATE_FW_INIT, state = "
- "0x%x for scsi%d\n", abs_state,
- instance->host->host_no);
- continue;
- }
-
/* Wait for FW to become ready */
if (megasas_transition_to_ready(instance, 1)) {
- printk(KERN_WARNING "megaraid_sas: Failed to "
+ dev_warn(&instance->pdev->dev, "Failed to "
"transition controller to ready "
"for scsi%d.\n",
instance->host->host_no);
@@ -2783,51 +2906,14 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
megasas_reset_reply_desc(instance);
if (megasas_ioc_init_fusion(instance)) {
- printk(KERN_WARNING "megaraid_sas: "
+ dev_warn(&instance->pdev->dev,
"megasas_ioc_init_fusion() failed!"
" for scsi%d\n",
instance->host->host_no);
continue;
}
- /* Re-fire management commands */
- for (j = 0 ; j < instance->max_fw_cmds; j++) {
- cmd_fusion = fusion->cmd_list[j];
- if (cmd_fusion->sync_cmd_idx !=
- (u32)ULONG_MAX) {
- cmd_mfi =
- instance->
- cmd_list[cmd_fusion->sync_cmd_idx];
- if (cmd_mfi->frame->dcmd.opcode ==
- cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)) {
- megasas_return_mfi_mpt_pthr(instance, cmd_mfi, cmd_fusion);
- } else {
- req_desc =
- megasas_get_request_descriptor(
- instance,
- cmd_mfi->context.smid
- -1);
- if (!req_desc) {
- printk(KERN_WARNING
- "req_desc NULL"
- " for scsi%d\n",
- instance->host->host_no);
- /* Return leaked MPT
- frame */
- megasas_return_cmd_fusion(instance, cmd_fusion);
- } else {
- instance->instancet->
- fire_cmd(instance,
- req_desc->
- u.low,
- req_desc->
- u.high,
- instance->
- reg_set);
- }
- }
- }
- }
+ megasas_refire_mgmt_cmd(instance);
if (megasas_get_ctrl_info(instance)) {
dev_info(&instance->pdev->dev,
@@ -2844,6 +2930,8 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
if (!megasas_get_map_info(instance))
megasas_sync_map_info(instance);
+ megasas_setup_jbod_map(instance);
+
clear_bit(MEGASAS_FUSION_IN_RESET,
&instance->reset_flags);
instance->instancet->enable_intr(instance);
@@ -2861,7 +2949,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
}
/* Adapter reset completed successfully */
- printk(KERN_WARNING "megaraid_sas: Reset "
+ dev_warn(&instance->pdev->dev, "Reset "
"successful for scsi%d.\n",
instance->host->host_no);
@@ -2877,7 +2965,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
goto out;
}
/* Reset failed, kill the adapter */
- printk(KERN_WARNING "megaraid_sas: Reset failed, killing "
+ dev_warn(&instance->pdev->dev, "Reset failed, killing "
"adapter scsi%d.\n", instance->host->host_no);
megaraid_sas_kill_hba(instance);
instance->skip_heartbeat_timer_del = 1;
@@ -2978,7 +3066,6 @@ void megasas_fusion_ocr_wq(struct work_struct *work)
}
struct megasas_instance_template megasas_instance_template_fusion = {
- .fire_cmd = megasas_fire_cmd_fusion,
.enable_intr = megasas_enable_intr_fusion,
.disable_intr = megasas_disable_intr_fusion,
.clear_intr = megasas_clear_intr_fusion,
diff --git a/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.h b/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 56e6db2d5..473005c99 100644
--- a/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/kernel/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -35,8 +35,13 @@
#define _MEGARAID_SAS_FUSION_H_
/* Fusion defines */
-#define MEGASAS_MAX_SZ_CHAIN_FRAME 1024
+#define MEGASAS_CHAIN_FRAME_SZ_MIN 1024
#define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000009)
+#define MEGASAS_MAX_CHAIN_SHIFT 5
+#define MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK 0x400000
+#define MEGASAS_MAX_CHAIN_SIZE_MASK 0x3E0
+#define MEGASAS_256K_IO 128
+#define MEGASAS_1MB_IO (MEGASAS_256K_IO * 4)
#define MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE 256
#define MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST 0xF0
#define MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST 0xF1
@@ -89,6 +94,12 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
#define MEGASAS_FP_CMD_LEN 16
#define MEGASAS_FUSION_IN_RESET 0
#define THRESHOLD_REPLY_COUNT 50
+#define JBOD_MAPS_COUNT 2
+
+enum MR_FUSION_ADAPTER_TYPE {
+ THUNDERBOLT_SERIES = 0,
+ INVADER_SERIES = 1,
+};
/*
* Raid Context structure which describes MegaRAID specific IO Parameters
@@ -104,20 +115,22 @@ struct RAID_CONTEXT {
u8 nseg:4;
#endif
u8 resvd0;
- u16 timeoutValue;
+ __le16 timeoutValue;
u8 regLockFlags;
u8 resvd1;
- u16 VirtualDiskTgtId;
- u64 regLockRowLBA;
- u32 regLockLength;
- u16 nextLMId;
+ __le16 VirtualDiskTgtId;
+ __le64 regLockRowLBA;
+ __le32 regLockLength;
+ __le16 nextLMId;
u8 exStatus;
u8 status;
u8 RAIDFlags;
u8 numSGE;
- u16 configSeqNum;
+ __le16 configSeqNum;
u8 spanArm;
- u8 resvd2[3];
+ u8 priority;
+ u8 numSGEExt;
+ u8 resvd2;
};
#define RAID_CTX_SPANARM_ARM_SHIFT (0)
@@ -182,61 +195,61 @@ enum REGION_TYPE {
#define MPI2_WRSEQ_6TH_KEY_VALUE (0xD)
struct MPI25_IEEE_SGE_CHAIN64 {
- u64 Address;
- u32 Length;
- u16 Reserved1;
+ __le64 Address;
+ __le32 Length;
+ __le16 Reserved1;
u8 NextChainOffset;
u8 Flags;
};
struct MPI2_SGE_SIMPLE_UNION {
- u32 FlagsLength;
+ __le32 FlagsLength;
union {
- u32 Address32;
- u64 Address64;
+ __le32 Address32;
+ __le64 Address64;
} u;
};
struct MPI2_SCSI_IO_CDB_EEDP32 {
u8 CDB[20]; /* 0x00 */
- u32 PrimaryReferenceTag; /* 0x14 */
- u16 PrimaryApplicationTag; /* 0x18 */
- u16 PrimaryApplicationTagMask; /* 0x1A */
- u32 TransferLength; /* 0x1C */
+ __be32 PrimaryReferenceTag; /* 0x14 */
+ __be16 PrimaryApplicationTag; /* 0x18 */
+ __be16 PrimaryApplicationTagMask; /* 0x1A */
+ __le32 TransferLength; /* 0x1C */
};
struct MPI2_SGE_CHAIN_UNION {
- u16 Length;
+ __le16 Length;
u8 NextChainOffset;
u8 Flags;
union {
- u32 Address32;
- u64 Address64;
+ __le32 Address32;
+ __le64 Address64;
} u;
};
struct MPI2_IEEE_SGE_SIMPLE32 {
- u32 Address;
- u32 FlagsLength;
+ __le32 Address;
+ __le32 FlagsLength;
};
struct MPI2_IEEE_SGE_CHAIN32 {
- u32 Address;
- u32 FlagsLength;
+ __le32 Address;
+ __le32 FlagsLength;
};
struct MPI2_IEEE_SGE_SIMPLE64 {
- u64 Address;
- u32 Length;
- u16 Reserved1;
+ __le64 Address;
+ __le32 Length;
+ __le16 Reserved1;
u8 Reserved2;
u8 Flags;
};
struct MPI2_IEEE_SGE_CHAIN64 {
- u64 Address;
- u32 Length;
- u16 Reserved1;
+ __le64 Address;
+ __le32 Length;
+ __le16 Reserved1;
u8 Reserved2;
u8 Flags;
};
@@ -269,34 +282,34 @@ union MPI2_SCSI_IO_CDB_UNION {
* Total SGE count will be one less than _MPI2_SCSI_IO_REQUEST
*/
struct MPI2_RAID_SCSI_IO_REQUEST {
- u16 DevHandle; /* 0x00 */
+ __le16 DevHandle; /* 0x00 */
u8 ChainOffset; /* 0x02 */
u8 Function; /* 0x03 */
- u16 Reserved1; /* 0x04 */
+ __le16 Reserved1; /* 0x04 */
u8 Reserved2; /* 0x06 */
u8 MsgFlags; /* 0x07 */
u8 VP_ID; /* 0x08 */
u8 VF_ID; /* 0x09 */
- u16 Reserved3; /* 0x0A */
- u32 SenseBufferLowAddress; /* 0x0C */
- u16 SGLFlags; /* 0x10 */
+ __le16 Reserved3; /* 0x0A */
+ __le32 SenseBufferLowAddress; /* 0x0C */
+ __le16 SGLFlags; /* 0x10 */
u8 SenseBufferLength; /* 0x12 */
u8 Reserved4; /* 0x13 */
u8 SGLOffset0; /* 0x14 */
u8 SGLOffset1; /* 0x15 */
u8 SGLOffset2; /* 0x16 */
u8 SGLOffset3; /* 0x17 */
- u32 SkipCount; /* 0x18 */
- u32 DataLength; /* 0x1C */
- u32 BidirectionalDataLength; /* 0x20 */
- u16 IoFlags; /* 0x24 */
- u16 EEDPFlags; /* 0x26 */
- u32 EEDPBlockSize; /* 0x28 */
- u32 SecondaryReferenceTag; /* 0x2C */
- u16 SecondaryApplicationTag; /* 0x30 */
- u16 ApplicationTagTranslationMask; /* 0x32 */
+ __le32 SkipCount; /* 0x18 */
+ __le32 DataLength; /* 0x1C */
+ __le32 BidirectionalDataLength; /* 0x20 */
+ __le16 IoFlags; /* 0x24 */
+ __le16 EEDPFlags; /* 0x26 */
+ __le32 EEDPBlockSize; /* 0x28 */
+ __le32 SecondaryReferenceTag; /* 0x2C */
+ __le16 SecondaryApplicationTag; /* 0x30 */
+ __le16 ApplicationTagTranslationMask; /* 0x32 */
u8 LUN[8]; /* 0x34 */
- u32 Control; /* 0x3C */
+ __le32 Control; /* 0x3C */
union MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */
struct RAID_CONTEXT RaidContext; /* 0x60 */
union MPI2_SGE_IO_UNION SGL; /* 0x80 */
@@ -315,45 +328,45 @@ struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR {
struct MPI2_DEFAULT_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u16 LMID; /* 0x04 */
- u16 DescriptorTypeDependent; /* 0x06 */
+ __le16 SMID; /* 0x02 */
+ __le16 LMID; /* 0x04 */
+ __le16 DescriptorTypeDependent; /* 0x06 */
};
/* High Priority Request Descriptor */
struct MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u16 LMID; /* 0x04 */
- u16 Reserved1; /* 0x06 */
+ __le16 SMID; /* 0x02 */
+ __le16 LMID; /* 0x04 */
+ __le16 Reserved1; /* 0x06 */
};
/* SCSI IO Request Descriptor */
struct MPI2_SCSI_IO_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u16 LMID; /* 0x04 */
- u16 DevHandle; /* 0x06 */
+ __le16 SMID; /* 0x02 */
+ __le16 LMID; /* 0x04 */
+ __le16 DevHandle; /* 0x06 */
};
/* SCSI Target Request Descriptor */
struct MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u16 LMID; /* 0x04 */
- u16 IoIndex; /* 0x06 */
+ __le16 SMID; /* 0x02 */
+ __le16 LMID; /* 0x04 */
+ __le16 IoIndex; /* 0x06 */
};
/* RAID Accelerator Request Descriptor */
struct MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u16 LMID; /* 0x04 */
- u16 Reserved; /* 0x06 */
+ __le16 SMID; /* 0x02 */
+ __le16 LMID; /* 0x04 */
+ __le16 Reserved; /* 0x06 */
};
/* union of Request Descriptors */
@@ -366,10 +379,10 @@ union MEGASAS_REQUEST_DESCRIPTOR_UNION {
struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR MFAIo;
union {
struct {
- u32 low;
- u32 high;
+ __le32 low;
+ __le32 high;
} u;
- u64 Words;
+ __le64 Words;
};
};
@@ -377,35 +390,35 @@ union MEGASAS_REQUEST_DESCRIPTOR_UNION {
struct MPI2_DEFAULT_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 DescriptorTypeDependent1; /* 0x02 */
- u32 DescriptorTypeDependent2; /* 0x04 */
+ __le16 DescriptorTypeDependent1; /* 0x02 */
+ __le32 DescriptorTypeDependent2; /* 0x04 */
};
/* Address Reply Descriptor */
struct MPI2_ADDRESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u32 ReplyFrameAddress; /* 0x04 */
+ __le16 SMID; /* 0x02 */
+ __le32 ReplyFrameAddress; /* 0x04 */
};
/* SCSI IO Success Reply Descriptor */
struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u16 TaskTag; /* 0x04 */
- u16 Reserved1; /* 0x06 */
+ __le16 SMID; /* 0x02 */
+ __le16 TaskTag; /* 0x04 */
+ __le16 Reserved1; /* 0x06 */
};
/* TargetAssist Success Reply Descriptor */
struct MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
+ __le16 SMID; /* 0x02 */
u8 SequenceNumber; /* 0x04 */
u8 Reserved1; /* 0x05 */
- u16 IoIndex; /* 0x06 */
+ __le16 IoIndex; /* 0x06 */
};
/* Target Command Buffer Reply Descriptor */
@@ -414,16 +427,16 @@ struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR {
u8 MSIxIndex; /* 0x01 */
u8 VP_ID; /* 0x02 */
u8 Flags; /* 0x03 */
- u16 InitiatorDevHandle; /* 0x04 */
- u16 IoIndex; /* 0x06 */
+ __le16 InitiatorDevHandle; /* 0x04 */
+ __le16 IoIndex; /* 0x06 */
};
/* RAID Accelerator Success Reply Descriptor */
struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
- u16 SMID; /* 0x02 */
- u32 Reserved; /* 0x04 */
+ __le16 SMID; /* 0x02 */
+ __le32 Reserved; /* 0x04 */
};
/* union of Reply Descriptors */
@@ -435,7 +448,7 @@ union MPI2_REPLY_DESCRIPTORS_UNION {
struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
RAIDAcceleratorSuccess;
- u64 Words;
+ __le64 Words;
};
/* IOCInit Request message */
@@ -444,28 +457,28 @@ struct MPI2_IOC_INIT_REQUEST {
u8 Reserved1; /* 0x01 */
u8 ChainOffset; /* 0x02 */
u8 Function; /* 0x03 */
- u16 Reserved2; /* 0x04 */
+ __le16 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 */
+ __le16 Reserved4; /* 0x0A */
+ __le16 MsgVersion; /* 0x0C */
+ __le16 HeaderVersion; /* 0x0E */
u32 Reserved5; /* 0x10 */
- u16 Reserved6; /* 0x14 */
+ __le16 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 */
+ __le16 Reserved8; /* 0x18 */
+ __le16 SystemRequestFrameSize; /* 0x1A */
+ __le16 ReplyDescriptorPostQueueDepth; /* 0x1C */
+ __le16 ReplyFreeQueueDepth; /* 0x1E */
+ __le32 SenseBufferAddressHigh; /* 0x20 */
+ __le32 SystemReplyAddressHigh; /* 0x24 */
+ __le64 SystemRequestFrameBaseAddress; /* 0x28 */
+ __le64 ReplyDescriptorPostQueueAddress;/* 0x30 */
+ __le64 ReplyFreeQueueAddress; /* 0x38 */
+ __le64 TimeStamp; /* 0x40 */
};
/* mrpriv defines */
@@ -486,46 +499,47 @@ struct MPI2_IOC_INIT_REQUEST {
#define MAX_PHYSICAL_DEVICES 256
#define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
#define MR_DCMD_LD_MAP_GET_INFO 0x0300e101
+#define MR_DCMD_SYSTEM_PD_MAP_GET_INFO 0x0200e102
#define MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC 0x010e8485 /* SR-IOV HB alloc*/
#define MR_DCMD_LD_VF_MAP_GET_ALL_LDS_111 0x03200200
#define MR_DCMD_LD_VF_MAP_GET_ALL_LDS 0x03150200
struct MR_DEV_HANDLE_INFO {
- u16 curDevHdl;
+ __le16 curDevHdl;
u8 validHandles;
u8 reserved;
- u16 devHandle[2];
+ __le16 devHandle[2];
};
struct MR_ARRAY_INFO {
- u16 pd[MAX_RAIDMAP_ROW_SIZE];
+ __le16 pd[MAX_RAIDMAP_ROW_SIZE];
};
struct MR_QUAD_ELEMENT {
- u64 logStart;
- u64 logEnd;
- u64 offsetInSpan;
- u32 diff;
- u32 reserved1;
+ __le64 logStart;
+ __le64 logEnd;
+ __le64 offsetInSpan;
+ __le32 diff;
+ __le32 reserved1;
};
struct MR_SPAN_INFO {
- u32 noElements;
- u32 reserved1;
+ __le32 noElements;
+ __le32 reserved1;
struct MR_QUAD_ELEMENT quad[MAX_RAIDMAP_SPAN_DEPTH];
};
struct MR_LD_SPAN {
- u64 startBlk;
- u64 numBlks;
- u16 arrayRef;
+ __le64 startBlk;
+ __le64 numBlks;
+ __le16 arrayRef;
u8 spanRowSize;
u8 spanRowDataSize;
u8 reserved[4];
};
struct MR_SPAN_BLOCK_INFO {
- u64 num_rows;
+ __le64 num_rows;
struct MR_LD_SPAN span;
struct MR_SPAN_INFO block_span_info;
};
@@ -558,8 +572,8 @@ struct MR_LD_RAID {
u32 reserved4:7;
#endif
} capability;
- u32 reserved6;
- u64 size;
+ __le32 reserved6;
+ __le64 size;
u8 spanDepth;
u8 level;
u8 stripeShift;
@@ -568,12 +582,12 @@ struct MR_LD_RAID {
u8 writeMode;
u8 PRL;
u8 SRL;
- u16 targetId;
+ __le16 targetId;
u8 ldState;
u8 regTypeReqOnWrite;
u8 modFactor;
u8 regTypeReqOnRead;
- u16 seqNum;
+ __le16 seqNum;
struct {
u32 ldSyncRequired:1;
@@ -592,20 +606,20 @@ struct MR_LD_SPAN_MAP {
};
struct MR_FW_RAID_MAP {
- u32 totalSize;
+ __le32 totalSize;
union {
struct {
- u32 maxLd;
- u32 maxSpanDepth;
- u32 maxRowSize;
- u32 maxPdCount;
- u32 maxArrays;
+ __le32 maxLd;
+ __le32 maxSpanDepth;
+ __le32 maxRowSize;
+ __le32 maxPdCount;
+ __le32 maxArrays;
} validationInfo;
- u32 version[5];
+ __le32 version[5];
};
- u32 ldCount;
- u32 Reserved1;
+ __le32 ldCount;
+ __le32 Reserved1;
u8 ldTgtIdToLd[MAX_RAIDMAP_LOGICAL_DRIVES+
MAX_RAIDMAP_VIEWS];
u8 fpPdIoTimeoutSec;
@@ -620,7 +634,7 @@ struct IO_REQUEST_INFO {
u32 numBlocks;
u16 ldTgtId;
u8 isRead;
- u16 devHandle;
+ __le16 devHandle;
u64 pdBlock;
u8 fpOkForIo;
u8 IoforUnevenSpan;
@@ -634,7 +648,7 @@ struct IO_REQUEST_INFO {
struct MR_LD_TARGET_SYNC {
u8 targetId;
u8 reserved;
- u16 seqNum;
+ __le16 seqNum;
};
#define IEEE_SGE_FLAGS_ADDR_MASK (0x03)
@@ -679,7 +693,6 @@ struct megasas_cmd_fusion {
*/
u32 sync_cmd_idx;
u32 index;
- u8 flags;
u8 pd_r1_lb;
};
@@ -720,27 +733,27 @@ struct MR_DRV_RAID_MAP {
* This feild will be manupulated by driver for ext raid map,
* else pick the value from firmware raid map.
*/
- u32 totalSize;
+ __le32 totalSize;
union {
struct {
- u32 maxLd;
- u32 maxSpanDepth;
- u32 maxRowSize;
- u32 maxPdCount;
- u32 maxArrays;
+ __le32 maxLd;
+ __le32 maxSpanDepth;
+ __le32 maxRowSize;
+ __le32 maxPdCount;
+ __le32 maxArrays;
} validationInfo;
- u32 version[5];
+ __le32 version[5];
};
/* timeout value used by driver in FP IOs*/
u8 fpPdIoTimeoutSec;
u8 reserved2[7];
- u16 ldCount;
- u16 arCount;
- u16 spanCount;
- u16 reserve3;
+ __le16 ldCount;
+ __le16 arCount;
+ __le16 spanCount;
+ __le16 reserve3;
struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT];
@@ -779,10 +792,10 @@ struct MR_FW_RAID_MAP_EXT {
u8 fpPdIoTimeoutSec;
u8 reserved2[7];
- u16 ldCount;
- u16 arCount;
- u16 spanCount;
- u16 reserve3;
+ __le16 ldCount;
+ __le16 arCount;
+ __le16 spanCount;
+ __le16 reserve3;
struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT];
@@ -790,12 +803,23 @@ struct MR_FW_RAID_MAP_EXT {
struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_EXT];
};
-struct fusion_context {
- struct megasas_cmd_fusion **cmd_list;
- struct list_head cmd_pool;
+/*
+ * * define MR_PD_CFG_SEQ structure for system PDs
+ * */
+struct MR_PD_CFG_SEQ {
+ __le16 seqNum;
+ __le16 devHandle;
+ u8 reserved[4];
+} __packed;
- spinlock_t mpt_pool_lock;
+struct MR_PD_CFG_SEQ_NUM_SYNC {
+ __le32 size;
+ __le32 count;
+ struct MR_PD_CFG_SEQ seq[1];
+} __packed;
+struct fusion_context {
+ struct megasas_cmd_fusion **cmd_list;
dma_addr_t req_frames_desc_phys;
u8 *req_frames_desc;
@@ -833,16 +857,19 @@ struct fusion_context {
u32 current_map_sz;
u32 drv_map_sz;
u32 drv_map_pages;
+ struct MR_PD_CFG_SEQ_NUM_SYNC *pd_seq_sync[JBOD_MAPS_COUNT];
+ dma_addr_t pd_seq_phys[JBOD_MAPS_COUNT];
u8 fast_path_io;
struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
+ u8 adapter_type;
};
union desc_value {
- u64 word;
+ __le64 word;
struct {
- u32 low;
- u32 high;
+ __le32 low;
+ __le32 high;
} u;
};