aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid/megaraid_sas_fusion.c
diff options
context:
space:
mode:
authorSumit.Saxena@lsi.com <Sumit.Saxena@lsi.com>2013-05-22 03:04:14 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-06-24 20:46:31 -0400
commitd46a3ad679c7232b72b21c6d0ca047dc4a68063f (patch)
treecae11de87870963d335838e24b01814081e0cbf8 /drivers/scsi/megaraid/megaraid_sas_fusion.c
parent5d0d908d4481187070cc94664417ab347f15d1fe (diff)
[SCSI] megaraid_sas: Add support for Extended MSI-x vectors for 12Gb/s controller
This Driver will use more than 8 MSI-x support provided by Invader/Fury max upto 128 MSI-x. [jejb: fix checkpatch warning] Signed-off-by: Sumit Saxena <sumit.saxena@lsi.com> Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas_fusion.c')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index c60f478c5aac..748b8ac5e1c3 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -101,8 +101,10 @@ extern int resetwaittime;
101 * @regs: MFI register set 101 * @regs: MFI register set
102 */ 102 */
103void 103void
104megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs) 104megasas_enable_intr_fusion(struct megasas_instance *instance)
105{ 105{
106 struct megasas_register_set __iomem *regs;
107 regs = instance->reg_set;
106 /* For Thunderbolt/Invader also clear intr on enable */ 108 /* For Thunderbolt/Invader also clear intr on enable */
107 writel(~0, &regs->outbound_intr_status); 109 writel(~0, &regs->outbound_intr_status);
108 readl(&regs->outbound_intr_status); 110 readl(&regs->outbound_intr_status);
@@ -111,6 +113,7 @@ megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs)
111 113
112 /* Dummy readl to force pci flush */ 114 /* Dummy readl to force pci flush */
113 readl(&regs->outbound_intr_mask); 115 readl(&regs->outbound_intr_mask);
116 instance->mask_interrupts = 0;
114} 117}
115 118
116/** 119/**
@@ -118,10 +121,13 @@ megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs)
118 * @regs: MFI register set 121 * @regs: MFI register set
119 */ 122 */
120void 123void
121megasas_disable_intr_fusion(struct megasas_register_set __iomem *regs) 124megasas_disable_intr_fusion(struct megasas_instance *instance)
122{ 125{
123 u32 mask = 0xFFFFFFFF; 126 u32 mask = 0xFFFFFFFF;
124 u32 status; 127 u32 status;
128 struct megasas_register_set __iomem *regs;
129 regs = instance->reg_set;
130 instance->mask_interrupts = 1;
125 131
126 writel(mask, &regs->outbound_intr_mask); 132 writel(mask, &regs->outbound_intr_mask);
127 /* Dummy readl to force pci flush */ 133 /* Dummy readl to force pci flush */
@@ -643,6 +649,12 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
643 init_frame->cmd = MFI_CMD_INIT; 649 init_frame->cmd = MFI_CMD_INIT;
644 init_frame->cmd_status = 0xFF; 650 init_frame->cmd_status = 0xFF;
645 651
652 /* driver support Extended MSIX */
653 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
654 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
655 init_frame->driver_operations.
656 mfi_capabilities.support_additional_msix = 1;
657
646 init_frame->queue_info_new_phys_addr_lo = ioc_init_handle; 658 init_frame->queue_info_new_phys_addr_lo = ioc_init_handle;
647 init_frame->data_xfer_len = sizeof(struct MPI2_IOC_INIT_REQUEST); 659 init_frame->data_xfer_len = sizeof(struct MPI2_IOC_INIT_REQUEST);
648 660
@@ -657,7 +669,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
657 /* 669 /*
658 * disable the intr before firing the init frame 670 * disable the intr before firing the init frame
659 */ 671 */
660 instance->instancet->disable_intr(instance->reg_set); 672 instance->instancet->disable_intr(instance);
661 673
662 for (i = 0; i < (10 * 1000); i += 20) { 674 for (i = 0; i < (10 * 1000); i += 20) {
663 if (readl(&instance->reg_set->doorbell) & 1) 675 if (readl(&instance->reg_set->doorbell) & 1)
@@ -1911,8 +1923,15 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
1911 return IRQ_NONE; 1923 return IRQ_NONE;
1912 1924
1913 wmb(); 1925 wmb();
1914 writel((MSIxIndex << 24) | fusion->last_reply_idx[MSIxIndex], 1926 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
1915 &instance->reg_set->reply_post_host_index); 1927 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
1928 writel(((MSIxIndex & 0x7) << 24) |
1929 fusion->last_reply_idx[MSIxIndex],
1930 instance->reply_post_host_index_addr[MSIxIndex/8]);
1931 else
1932 writel((MSIxIndex << 24) |
1933 fusion->last_reply_idx[MSIxIndex],
1934 instance->reply_post_host_index_addr[0]);
1916 megasas_check_and_restore_queue_depth(instance); 1935 megasas_check_and_restore_queue_depth(instance);
1917 return IRQ_HANDLED; 1936 return IRQ_HANDLED;
1918} 1937}
@@ -1954,6 +1973,9 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp)
1954 struct megasas_instance *instance = irq_context->instance; 1973 struct megasas_instance *instance = irq_context->instance;
1955 u32 mfiStatus, fw_state; 1974 u32 mfiStatus, fw_state;
1956 1975
1976 if (instance->mask_interrupts)
1977 return IRQ_NONE;
1978
1957 if (!instance->msix_vectors) { 1979 if (!instance->msix_vectors) {
1958 mfiStatus = instance->instancet->clear_intr(instance->reg_set); 1980 mfiStatus = instance->instancet->clear_intr(instance->reg_set);
1959 if (!mfiStatus) 1981 if (!mfiStatus)
@@ -2219,7 +2241,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
2219 mutex_lock(&instance->reset_mutex); 2241 mutex_lock(&instance->reset_mutex);
2220 set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); 2242 set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
2221 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; 2243 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
2222 instance->instancet->disable_intr(instance->reg_set); 2244 instance->instancet->disable_intr(instance);
2223 msleep(1000); 2245 msleep(1000);
2224 2246
2225 /* First try waiting for commands to complete */ 2247 /* First try waiting for commands to complete */
@@ -2343,7 +2365,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
2343 2365
2344 clear_bit(MEGASAS_FUSION_IN_RESET, 2366 clear_bit(MEGASAS_FUSION_IN_RESET,
2345 &instance->reset_flags); 2367 &instance->reset_flags);
2346 instance->instancet->enable_intr(instance->reg_set); 2368 instance->instancet->enable_intr(instance);
2347 instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 2369 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2348 2370
2349 /* Re-fire management commands */ 2371 /* Re-fire management commands */
@@ -2405,7 +2427,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
2405 retval = FAILED; 2427 retval = FAILED;
2406 } else { 2428 } else {
2407 clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); 2429 clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
2408 instance->instancet->enable_intr(instance->reg_set); 2430 instance->instancet->enable_intr(instance);
2409 instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 2431 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2410 } 2432 }
2411out: 2433out: