diff options
author | Sumit.Saxena@lsi.com <Sumit.Saxena@lsi.com> | 2013-05-22 03:04:14 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-06-24 20:46:31 -0400 |
commit | d46a3ad679c7232b72b21c6d0ca047dc4a68063f (patch) | |
tree | cae11de87870963d335838e24b01814081e0cbf8 /drivers/scsi/megaraid/megaraid_sas_fusion.c | |
parent | 5d0d908d4481187070cc94664417ab347f15d1fe (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.c | 38 |
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 | */ |
103 | void | 103 | void |
104 | megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs) | 104 | megasas_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, ®s->outbound_intr_status); | 109 | writel(~0, ®s->outbound_intr_status); |
108 | readl(®s->outbound_intr_status); | 110 | readl(®s->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(®s->outbound_intr_mask); | 115 | readl(®s->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 | */ |
120 | void | 123 | void |
121 | megasas_disable_intr_fusion(struct megasas_register_set __iomem *regs) | 124 | megasas_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, ®s->outbound_intr_mask); | 132 | writel(mask, ®s->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 | } |
2411 | out: | 2433 | out: |