diff options
author | adam radford <aradford@gmail.com> | 2011-10-08 21:15:06 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-10-16 12:21:08 -0400 |
commit | 36807e6799dcd8f961137b74c7edce10c6fcb1d2 (patch) | |
tree | f3fe7ee5b1d8663aaf57fe98e4ecfca4d7842b8d /drivers/scsi/megaraid | |
parent | 3f0e58bc8ff80e173660bdfcc514d8a5c4419764 (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.h | 2 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_base.c | 39 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fp.c | 26 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fusion.c | 96 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fusion.h | 16 |
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); |
4163 | fail_irq: | 4179 | fail_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 | */ |
229 | u8 MR_GetPhyParams(u32 ld, u64 stripRow, u16 stripRef, u64 *pdBlock, | 230 | u8 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 | */ |
308 | u8 | 311 | u8 |
309 | MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info, | 312 | MR_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 | ||
76 | u8 | 76 | u8 |
77 | MR_BuildRaidContext(struct IO_REQUEST_INFO *io_info, | 77 | MR_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); |
80 | u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map); | 81 | u16 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 | ||
84 | struct RAID_CONTEXT { | 92 | struct 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 { |