aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authoradam radford <aradford@gmail.com>2011-10-08 21:15:06 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-16 12:21:08 -0400
commit36807e6799dcd8f961137b74c7edce10c6fcb1d2 (patch)
treef3fe7ee5b1d8663aaf57fe98e4ecfca4d7842b8d /drivers/scsi/megaraid
parent3f0e58bc8ff80e173660bdfcc514d8a5c4419764 (diff)
[SCSI] megaraid_sas: Add support for MegaRAID 9360/9380 12GB/s controllers
Signed-off-by: Adam Radford <aradford@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c39
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fp.c26
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c96
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.h16
5 files changed, 139 insertions, 40 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index bc83eaad507b..6b3562554937 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -48,6 +48,7 @@
48#define PCI_DEVICE_ID_LSI_SAS0073SKINNY 0x0073 48#define PCI_DEVICE_ID_LSI_SAS0073SKINNY 0x0073
49#define PCI_DEVICE_ID_LSI_SAS0071SKINNY 0x0071 49#define PCI_DEVICE_ID_LSI_SAS0071SKINNY 0x0071
50#define PCI_DEVICE_ID_LSI_FUSION 0x005b 50#define PCI_DEVICE_ID_LSI_FUSION 0x005b
51#define PCI_DEVICE_ID_LSI_INVADER 0x005d
51 52
52/* 53/*
53 * ===================================== 54 * =====================================
@@ -221,6 +222,7 @@ enum MFI_STAT {
221 MFI_STAT_RESERVATION_IN_PROGRESS = 0x36, 222 MFI_STAT_RESERVATION_IN_PROGRESS = 0x36,
222 MFI_STAT_I2C_ERRORS_DETECTED = 0x37, 223 MFI_STAT_I2C_ERRORS_DETECTED = 0x37,
223 MFI_STAT_PCI_ERRORS_DETECTED = 0x38, 224 MFI_STAT_PCI_ERRORS_DETECTED = 0x38,
225 MFI_STAT_CONFIG_SEQ_MISMATCH = 0x67,
224 226
225 MFI_STAT_INVALID_STATUS = 0xFF 227 MFI_STAT_INVALID_STATUS = 0xFF
226}; 228};
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 9d5a14a2c5b1..f2cf768c896d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -114,6 +114,8 @@ static struct pci_device_id megasas_pci_table[] = {
114 /* xscale IOP */ 114 /* xscale IOP */
115 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)}, 115 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FUSION)},
116 /* Fusion */ 116 /* Fusion */
117 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)},
118 /* Invader */
117 {} 119 {}
118}; 120};
119 121
@@ -1583,7 +1585,8 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
1583{ 1585{
1584 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 1586 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1585 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 1587 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
1586 (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION)) { 1588 (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
1589 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) {
1587 writel(MFI_STOP_ADP, &instance->reg_set->doorbell); 1590 writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
1588 } else { 1591 } else {
1589 writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); 1592 writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell);
@@ -1957,7 +1960,8 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
1957 /* 1960 /*
1958 * First wait for all commands to complete 1961 * First wait for all commands to complete
1959 */ 1962 */
1960 if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) 1963 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
1964 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
1961 ret = megasas_reset_fusion(scmd->device->host); 1965 ret = megasas_reset_fusion(scmd->device->host);
1962 else 1966 else
1963 ret = megasas_generic_reset(scmd); 1967 ret = megasas_generic_reset(scmd);
@@ -2656,7 +2660,9 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
2656 (instance->pdev->device == 2660 (instance->pdev->device ==
2657 PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 2661 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
2658 (instance->pdev->device == 2662 (instance->pdev->device ==
2659 PCI_DEVICE_ID_LSI_FUSION)) { 2663 PCI_DEVICE_ID_LSI_FUSION) ||
2664 (instance->pdev->device ==
2665 PCI_DEVICE_ID_LSI_INVADER)) {
2660 writel( 2666 writel(
2661 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, 2667 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
2662 &instance->reg_set->doorbell); 2668 &instance->reg_set->doorbell);
@@ -2676,7 +2682,9 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
2676 (instance->pdev->device == 2682 (instance->pdev->device ==
2677 PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 2683 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
2678 (instance->pdev->device == 2684 (instance->pdev->device ==
2679 PCI_DEVICE_ID_LSI_FUSION)) { 2685 PCI_DEVICE_ID_LSI_FUSION) ||
2686 (instance->pdev->device ==
2687 PCI_DEVICE_ID_LSI_INVADER)) {
2680 writel(MFI_INIT_HOTPLUG, 2688 writel(MFI_INIT_HOTPLUG,
2681 &instance->reg_set->doorbell); 2689 &instance->reg_set->doorbell);
2682 } else 2690 } else
@@ -2697,11 +2705,15 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
2697 (instance->pdev->device == 2705 (instance->pdev->device ==
2698 PCI_DEVICE_ID_LSI_SAS0071SKINNY) || 2706 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
2699 (instance->pdev->device 2707 (instance->pdev->device
2700 == PCI_DEVICE_ID_LSI_FUSION)) { 2708 == PCI_DEVICE_ID_LSI_FUSION) ||
2709 (instance->pdev->device
2710 == PCI_DEVICE_ID_LSI_INVADER)) {
2701 writel(MFI_RESET_FLAGS, 2711 writel(MFI_RESET_FLAGS,
2702 &instance->reg_set->doorbell); 2712 &instance->reg_set->doorbell);
2703 if (instance->pdev->device == 2713 if ((instance->pdev->device ==
2704 PCI_DEVICE_ID_LSI_FUSION) { 2714 PCI_DEVICE_ID_LSI_FUSION) ||
2715 (instance->pdev->device ==
2716 PCI_DEVICE_ID_LSI_INVADER)) {
2705 for (i = 0; i < (10 * 1000); i += 20) { 2717 for (i = 0; i < (10 * 1000); i += 20) {
2706 if (readl( 2718 if (readl(
2707 &instance-> 2719 &instance->
@@ -3498,6 +3510,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
3498 3510
3499 switch (instance->pdev->device) { 3511 switch (instance->pdev->device) {
3500 case PCI_DEVICE_ID_LSI_FUSION: 3512 case PCI_DEVICE_ID_LSI_FUSION:
3513 case PCI_DEVICE_ID_LSI_INVADER:
3501 instance->instancet = &megasas_instance_template_fusion; 3514 instance->instancet = &megasas_instance_template_fusion;
3502 break; 3515 break;
3503 case PCI_DEVICE_ID_LSI_SAS1078R: 3516 case PCI_DEVICE_ID_LSI_SAS1078R:
@@ -3894,7 +3907,8 @@ static int megasas_io_attach(struct megasas_instance *instance)
3894 host->max_cmd_len = 16; 3907 host->max_cmd_len = 16;
3895 3908
3896 /* Fusion only supports host reset */ 3909 /* Fusion only supports host reset */
3897 if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) { 3910 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
3911 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) {
3898 host->hostt->eh_device_reset_handler = NULL; 3912 host->hostt->eh_device_reset_handler = NULL;
3899 host->hostt->eh_bus_reset_handler = NULL; 3913 host->hostt->eh_bus_reset_handler = NULL;
3900 } 3914 }
@@ -4004,6 +4018,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
4004 4018
4005 switch (instance->pdev->device) { 4019 switch (instance->pdev->device) {
4006 case PCI_DEVICE_ID_LSI_FUSION: 4020 case PCI_DEVICE_ID_LSI_FUSION:
4021 case PCI_DEVICE_ID_LSI_INVADER:
4007 { 4022 {
4008 struct fusion_context *fusion; 4023 struct fusion_context *fusion;
4009 4024
@@ -4096,7 +4111,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
4096 instance->last_time = 0; 4111 instance->last_time = 0;
4097 instance->disableOnlineCtrlReset = 1; 4112 instance->disableOnlineCtrlReset = 1;
4098 4113
4099 if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) 4114 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
4115 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
4100 INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); 4116 INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
4101 else 4117 else
4102 INIT_WORK(&instance->work_init, process_fw_state_change_wq); 4118 INIT_WORK(&instance->work_init, process_fw_state_change_wq);
@@ -4161,7 +4177,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
4161 free_irq(instance->msi_flag ? instance->msixentry.vector : 4177 free_irq(instance->msi_flag ? instance->msixentry.vector :
4162 instance->pdev->irq, instance); 4178 instance->pdev->irq, instance);
4163fail_irq: 4179fail_irq:
4164 if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) 4180 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
4181 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
4165 megasas_release_fusion(instance); 4182 megasas_release_fusion(instance);
4166 else 4183 else
4167 megasas_release_mfi(instance); 4184 megasas_release_mfi(instance);
@@ -4368,6 +4385,7 @@ megasas_resume(struct pci_dev *pdev)
4368 4385
4369 switch (instance->pdev->device) { 4386 switch (instance->pdev->device) {
4370 case PCI_DEVICE_ID_LSI_FUSION: 4387 case PCI_DEVICE_ID_LSI_FUSION:
4388 case PCI_DEVICE_ID_LSI_INVADER:
4371 { 4389 {
4372 megasas_reset_reply_desc(instance); 4390 megasas_reset_reply_desc(instance);
4373 if (megasas_ioc_init_fusion(instance)) { 4391 if (megasas_ioc_init_fusion(instance)) {
@@ -4501,6 +4519,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
4501 4519
4502 switch (instance->pdev->device) { 4520 switch (instance->pdev->device) {
4503 case PCI_DEVICE_ID_LSI_FUSION: 4521 case PCI_DEVICE_ID_LSI_FUSION:
4522 case PCI_DEVICE_ID_LSI_INVADER:
4504 megasas_release_fusion(instance); 4523 megasas_release_fusion(instance);
4505 for (i = 0; i < 2 ; i++) 4524 for (i = 0; i < 2 ; i++)
4506 if (fusion->ld_map[i]) 4525 if (fusion->ld_map[i])
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 5a5af1fe7581..5255dd688aca 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -52,6 +52,7 @@
52#include <scsi/scsi_host.h> 52#include <scsi/scsi_host.h>
53 53
54#include "megaraid_sas_fusion.h" 54#include "megaraid_sas_fusion.h"
55#include "megaraid_sas.h"
55#include <asm/div64.h> 56#include <asm/div64.h>
56 57
57#define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) 58#define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
@@ -226,8 +227,9 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
226* span - Span number 227* span - Span number
227* block - Absolute Block number in the physical disk 228* block - Absolute Block number in the physical disk
228*/ 229*/
229u8 MR_GetPhyParams(u32 ld, u64 stripRow, u16 stripRef, u64 *pdBlock, 230u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
230 u16 *pDevHandle, struct RAID_CONTEXT *pRAID_Context, 231 u16 stripRef, u64 *pdBlock, u16 *pDevHandle,
232 struct RAID_CONTEXT *pRAID_Context,
231 struct MR_FW_RAID_MAP_ALL *map) 233 struct MR_FW_RAID_MAP_ALL *map)
232{ 234{
233 struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); 235 struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map);
@@ -279,7 +281,8 @@ u8 MR_GetPhyParams(u32 ld, u64 stripRow, u16 stripRef, u64 *pdBlock,
279 *pDevHandle = MR_PdDevHandleGet(pd, map); 281 *pDevHandle = MR_PdDevHandleGet(pd, map);
280 else { 282 else {
281 *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */ 283 *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
282 if (raid->level >= 5) 284 if ((raid->level >= 5) &&
285 (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER))
283 pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; 286 pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
284 else if (raid->level == 1) { 287 else if (raid->level == 1) {
285 /* Get alternate Pd. */ 288 /* Get alternate Pd. */
@@ -306,7 +309,8 @@ u8 MR_GetPhyParams(u32 ld, u64 stripRow, u16 stripRef, u64 *pdBlock,
306* This function will return 0 if region lock was acquired OR return num strips 309* This function will return 0 if region lock was acquired OR return num strips
307*/ 310*/
308u8 311u8
309MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info, 312MR_BuildRaidContext(struct megasas_instance *instance,
313 struct IO_REQUEST_INFO *io_info,
310 struct RAID_CONTEXT *pRAID_Context, 314 struct RAID_CONTEXT *pRAID_Context,
311 struct MR_FW_RAID_MAP_ALL *map) 315 struct MR_FW_RAID_MAP_ALL *map)
312{ 316{
@@ -394,8 +398,12 @@ MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info,
394 } 398 }
395 399
396 pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec; 400 pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec;
397 pRAID_Context->regLockFlags = (isRead) ? REGION_TYPE_SHARED_READ : 401 if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
398 raid->regTypeReqOnWrite; 402 pRAID_Context->regLockFlags = (isRead) ?
403 raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
404 else
405 pRAID_Context->regLockFlags = (isRead) ?
406 REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite;
399 pRAID_Context->VirtualDiskTgtId = raid->targetId; 407 pRAID_Context->VirtualDiskTgtId = raid->targetId;
400 pRAID_Context->regLockRowLBA = regStart; 408 pRAID_Context->regLockRowLBA = regStart;
401 pRAID_Context->regLockLength = regSize; 409 pRAID_Context->regLockLength = regSize;
@@ -404,7 +412,8 @@ MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info,
404 /*Get Phy Params only if FP capable, or else leave it to MR firmware 412 /*Get Phy Params only if FP capable, or else leave it to MR firmware
405 to do the calculation.*/ 413 to do the calculation.*/
406 if (io_info->fpOkForIo) { 414 if (io_info->fpOkForIo) {
407 retval = MR_GetPhyParams(ld, start_strip, ref_in_start_stripe, 415 retval = MR_GetPhyParams(instance, ld, start_strip,
416 ref_in_start_stripe,
408 &io_info->pdBlock, 417 &io_info->pdBlock,
409 &io_info->devHandle, pRAID_Context, 418 &io_info->devHandle, pRAID_Context,
410 map); 419 map);
@@ -415,7 +424,8 @@ MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info,
415 } else if (isRead) { 424 } else if (isRead) {
416 uint stripIdx; 425 uint stripIdx;
417 for (stripIdx = 0; stripIdx < num_strips; stripIdx++) { 426 for (stripIdx = 0; stripIdx < num_strips; stripIdx++) {
418 if (!MR_GetPhyParams(ld, start_strip + stripIdx, 427 if (!MR_GetPhyParams(instance, ld,
428 start_strip + stripIdx,
419 ref_in_start_stripe, 429 ref_in_start_stripe,
420 &io_info->pdBlock, 430 &io_info->pdBlock,
421 &io_info->devHandle, 431 &io_info->devHandle,
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 120499ade9a5..ad6bd061a0f8 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -74,7 +74,8 @@ megasas_issue_polled(struct megasas_instance *instance,
74 struct megasas_cmd *cmd); 74 struct megasas_cmd *cmd);
75 75
76u8 76u8
77MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info, 77MR_BuildRaidContext(struct megasas_instance *instance,
78 struct IO_REQUEST_INFO *io_info,
78 struct RAID_CONTEXT *pRAID_Context, 79 struct RAID_CONTEXT *pRAID_Context,
79 struct MR_FW_RAID_MAP_ALL *map); 80 struct MR_FW_RAID_MAP_ALL *map);
80u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map); 81u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map);
@@ -1038,7 +1039,9 @@ map_cmd_status(struct megasas_cmd_fusion *cmd, u8 status, u8 ext_status)
1038 case MFI_STAT_DEVICE_NOT_FOUND: 1039 case MFI_STAT_DEVICE_NOT_FOUND:
1039 cmd->scmd->result = DID_BAD_TARGET << 16; 1040 cmd->scmd->result = DID_BAD_TARGET << 16;
1040 break; 1041 break;
1041 1042 case MFI_STAT_CONFIG_SEQ_MISMATCH:
1043 cmd->scmd->result = DID_IMM_RETRY << 16;
1044 break;
1042 default: 1045 default:
1043 printk(KERN_DEBUG "megasas: FW status %#x\n", status); 1046 printk(KERN_DEBUG "megasas: FW status %#x\n", status);
1044 cmd->scmd->result = DID_ERROR << 16; 1047 cmd->scmd->result = DID_ERROR << 16;
@@ -1061,14 +1064,17 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
1061 struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr, 1064 struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr,
1062 struct megasas_cmd_fusion *cmd) 1065 struct megasas_cmd_fusion *cmd)
1063{ 1066{
1064 int i, sg_processed; 1067 int i, sg_processed, sge_count;
1065 int sge_count, sge_idx;
1066 struct scatterlist *os_sgl; 1068 struct scatterlist *os_sgl;
1067 struct fusion_context *fusion; 1069 struct fusion_context *fusion;
1068 1070
1069 fusion = instance->ctrl_context; 1071 fusion = instance->ctrl_context;
1070 1072
1071 cmd->io_request->ChainOffset = 0; 1073 if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
1074 struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr;
1075 sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
1076 sgl_ptr_end->Flags = 0;
1077 }
1072 1078
1073 sge_count = scsi_dma_map(scp); 1079 sge_count = scsi_dma_map(scp);
1074 1080
@@ -1077,16 +1083,14 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
1077 if (sge_count > instance->max_num_sge || !sge_count) 1083 if (sge_count > instance->max_num_sge || !sge_count)
1078 return sge_count; 1084 return sge_count;
1079 1085
1080 if (sge_count > fusion->max_sge_in_main_msg) {
1081 /* One element to store the chain info */
1082 sge_idx = fusion->max_sge_in_main_msg - 1;
1083 } else
1084 sge_idx = sge_count;
1085
1086 scsi_for_each_sg(scp, os_sgl, sge_count, i) { 1086 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
1087 sgl_ptr->Length = sg_dma_len(os_sgl); 1087 sgl_ptr->Length = sg_dma_len(os_sgl);
1088 sgl_ptr->Address = sg_dma_address(os_sgl); 1088 sgl_ptr->Address = sg_dma_address(os_sgl);
1089 sgl_ptr->Flags = 0; 1089 sgl_ptr->Flags = 0;
1090 if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
1091 if (i == sge_count - 1)
1092 sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST;
1093 }
1090 sgl_ptr++; 1094 sgl_ptr++;
1091 1095
1092 sg_processed = i + 1; 1096 sg_processed = i + 1;
@@ -1095,13 +1099,30 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
1095 (sge_count > fusion->max_sge_in_main_msg)) { 1099 (sge_count > fusion->max_sge_in_main_msg)) {
1096 1100
1097 struct MPI25_IEEE_SGE_CHAIN64 *sg_chain; 1101 struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
1098 cmd->io_request->ChainOffset = 1102 if (instance->pdev->device ==
1099 fusion->chain_offset_io_request; 1103 PCI_DEVICE_ID_LSI_INVADER) {
1104 if ((cmd->io_request->IoFlags &
1105 MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
1106 MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)
1107 cmd->io_request->ChainOffset =
1108 fusion->
1109 chain_offset_io_request;
1110 else
1111 cmd->io_request->ChainOffset = 0;
1112 } else
1113 cmd->io_request->ChainOffset =
1114 fusion->chain_offset_io_request;
1115
1100 sg_chain = sgl_ptr; 1116 sg_chain = sgl_ptr;
1101 /* Prepare chain element */ 1117 /* Prepare chain element */
1102 sg_chain->NextChainOffset = 0; 1118 sg_chain->NextChainOffset = 0;
1103 sg_chain->Flags = (IEEE_SGE_FLAGS_CHAIN_ELEMENT | 1119 if (instance->pdev->device ==
1104 MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR); 1120 PCI_DEVICE_ID_LSI_INVADER)
1121 sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT;
1122 else
1123 sg_chain->Flags =
1124 (IEEE_SGE_FLAGS_CHAIN_ELEMENT |
1125 MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR);
1105 sg_chain->Length = (sizeof(union MPI2_SGE_IO_UNION) 1126 sg_chain->Length = (sizeof(union MPI2_SGE_IO_UNION)
1106 *(sge_count - sg_processed)); 1127 *(sge_count - sg_processed));
1107 sg_chain->Address = cmd->sg_frame_phys_addr; 1128 sg_chain->Address = cmd->sg_frame_phys_addr;
@@ -1394,7 +1415,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
1394 io_request->RaidContext.regLockFlags = 0; 1415 io_request->RaidContext.regLockFlags = 0;
1395 fp_possible = 0; 1416 fp_possible = 0;
1396 } else { 1417 } else {
1397 if (MR_BuildRaidContext(&io_info, &io_request->RaidContext, 1418 if (MR_BuildRaidContext(instance, &io_info,
1419 &io_request->RaidContext,
1398 local_map_ptr)) 1420 local_map_ptr))
1399 fp_possible = io_info.fpOkForIo; 1421 fp_possible = io_info.fpOkForIo;
1400 } 1422 }
@@ -1407,6 +1429,20 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
1407 cmd->request_desc->SCSIIO.RequestFlags = 1429 cmd->request_desc->SCSIIO.RequestFlags =
1408 (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY 1430 (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
1409 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 1431 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1432 if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
1433 if (io_request->RaidContext.regLockFlags ==
1434 REGION_TYPE_UNUSED)
1435 cmd->request_desc->SCSIIO.RequestFlags =
1436 (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
1437 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1438 io_request->RaidContext.Type = MPI2_TYPE_CUDA;
1439 io_request->RaidContext.nseg = 0x1;
1440 io_request->IoFlags |=
1441 MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
1442 io_request->RaidContext.regLockFlags |=
1443 (MR_RL_FLAGS_GRANT_DESTINATION_CUDA |
1444 MR_RL_FLAGS_SEQ_NUM_ENABLE);
1445 }
1410 if ((fusion->load_balance_info[device_id].loadBalanceFlag) && 1446 if ((fusion->load_balance_info[device_id].loadBalanceFlag) &&
1411 (io_info.isRead)) { 1447 (io_info.isRead)) {
1412 io_info.devHandle = 1448 io_info.devHandle =
@@ -1421,11 +1457,23 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
1421 } else { 1457 } else {
1422 io_request->RaidContext.timeoutValue = 1458 io_request->RaidContext.timeoutValue =
1423 local_map_ptr->raidMap.fpPdIoTimeoutSec; 1459 local_map_ptr->raidMap.fpPdIoTimeoutSec;
1424 io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
1425 io_request->DevHandle = device_id;
1426 cmd->request_desc->SCSIIO.RequestFlags = 1460 cmd->request_desc->SCSIIO.RequestFlags =
1427 (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO 1461 (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
1428 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 1462 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1463 if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
1464 if (io_request->RaidContext.regLockFlags ==
1465 REGION_TYPE_UNUSED)
1466 cmd->request_desc->SCSIIO.RequestFlags =
1467 (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
1468 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1469 io_request->RaidContext.Type = MPI2_TYPE_CUDA;
1470 io_request->RaidContext.regLockFlags |=
1471 (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 |
1472 MR_RL_FLAGS_SEQ_NUM_ENABLE);
1473 io_request->RaidContext.nseg = 0x1;
1474 }
1475 io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
1476 io_request->DevHandle = device_id;
1429 } /* Not FP */ 1477 } /* Not FP */
1430} 1478}
1431 1479
@@ -1508,8 +1556,10 @@ megasas_build_io_fusion(struct megasas_instance *instance,
1508 io_request->EEDPFlags = 0; 1556 io_request->EEDPFlags = 0;
1509 io_request->Control = 0; 1557 io_request->Control = 0;
1510 io_request->EEDPBlockSize = 0; 1558 io_request->EEDPBlockSize = 0;
1511 io_request->IoFlags = 0; 1559 io_request->ChainOffset = 0;
1512 io_request->RaidContext.RAIDFlags = 0; 1560 io_request->RaidContext.RAIDFlags = 0;
1561 io_request->RaidContext.Type = 0;
1562 io_request->RaidContext.nseg = 0;
1513 1563
1514 memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len); 1564 memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len);
1515 /* 1565 /*
@@ -1863,6 +1913,14 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
1863 1913
1864 fusion = instance->ctrl_context; 1914 fusion = instance->ctrl_context;
1865 io_req = cmd->io_request; 1915 io_req = cmd->io_request;
1916
1917 if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
1918 struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end =
1919 (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL;
1920 sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
1921 sgl_ptr_end->Flags = 0;
1922 }
1923
1866 mpi25_ieee_chain = 1924 mpi25_ieee_chain =
1867 (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL.IeeeChain; 1925 (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL.IeeeChain;
1868 1926
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 82b577a72c8b..9556c08490b2 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -44,6 +44,14 @@
44#define HOST_DIAG_RESET_ADAPTER 0x4 44#define HOST_DIAG_RESET_ADAPTER 0x4
45#define MEGASAS_FUSION_MAX_RESET_TRIES 3 45#define MEGASAS_FUSION_MAX_RESET_TRIES 3
46 46
47/* Invader defines */
48#define MPI2_TYPE_CUDA 0x2
49#define MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH 0x4000
50#define MR_RL_FLAGS_GRANT_DESTINATION_CPU0 0x00
51#define MR_RL_FLAGS_GRANT_DESTINATION_CPU1 0x10
52#define MR_RL_FLAGS_GRANT_DESTINATION_CUDA 0x80
53#define MR_RL_FLAGS_SEQ_NUM_ENABLE 0x8
54
47/* T10 PI defines */ 55/* T10 PI defines */
48#define MR_PROT_INFO_TYPE_CONTROLLER 0x8 56#define MR_PROT_INFO_TYPE_CONTROLLER 0x8
49#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD 0x7f 57#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD 0x7f
@@ -70,7 +78,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
70 */ 78 */
71#define MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO 0x7 79#define MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO 0x7
72#define MEGASAS_REQ_DESCRIPT_FLAGS_MFA 0x1 80#define MEGASAS_REQ_DESCRIPT_FLAGS_MFA 0x1
73 81#define MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK 0x2
74#define MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 1 82#define MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 1
75 83
76#define MEGASAS_FP_CMD_LEN 16 84#define MEGASAS_FP_CMD_LEN 16
@@ -82,7 +90,9 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
82 */ 90 */
83 91
84struct RAID_CONTEXT { 92struct RAID_CONTEXT {
85 u16 resvd0; 93 u8 Type:4;
94 u8 nseg:4;
95 u8 resvd0;
86 u16 timeoutValue; 96 u16 timeoutValue;
87 u8 regLockFlags; 97 u8 regLockFlags;
88 u8 resvd1; 98 u8 resvd1;
@@ -527,7 +537,7 @@ struct MR_LD_RAID {
527 u8 ldState; 537 u8 ldState;
528 u8 regTypeReqOnWrite; 538 u8 regTypeReqOnWrite;
529 u8 modFactor; 539 u8 modFactor;
530 u8 reserved2[1]; 540 u8 regTypeReqOnRead;
531 u16 seqNum; 541 u16 seqNum;
532 542
533 struct { 543 struct {