aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
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
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')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h25
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c111
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c38
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.h5
4 files changed, 136 insertions, 43 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 9504b519e121..2371e5ca2a5b 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -786,7 +786,7 @@ struct megasas_ctrl_info {
786#define MEGASAS_INT_CMDS 32 786#define MEGASAS_INT_CMDS 32
787#define MEGASAS_SKINNY_INT_CMDS 5 787#define MEGASAS_SKINNY_INT_CMDS 5
788 788
789#define MEGASAS_MAX_MSIX_QUEUES 16 789#define MEGASAS_MAX_MSIX_QUEUES 128
790/* 790/*
791 * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit 791 * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
792 * SGLs based on the size of dma_addr_t 792 * SGLs based on the size of dma_addr_t
@@ -811,6 +811,11 @@ struct megasas_ctrl_info {
811#define MFI_1068_PCSR_OFFSET 0x84 811#define MFI_1068_PCSR_OFFSET 0x84
812#define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 812#define MFI_1068_FW_HANDSHAKE_OFFSET 0x64
813#define MFI_1068_FW_READY 0xDDDD0000 813#define MFI_1068_FW_READY 0xDDDD0000
814
815#define MR_MAX_REPLY_QUEUES_OFFSET 0X0000001F
816#define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000
817#define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14
818#define MR_MAX_MSIX_REG_ARRAY 16
814/* 819/*
815* register set for both 1068 and 1078 controllers 820* register set for both 1068 and 1078 controllers
816* structure extended for 1078 registers 821* structure extended for 1078 registers
@@ -920,6 +925,15 @@ union megasas_sgl_frame {
920 925
921} __attribute__ ((packed)); 926} __attribute__ ((packed));
922 927
928typedef union _MFI_CAPABILITIES {
929 struct {
930 u32 support_fp_remote_lun:1;
931 u32 support_additional_msix:1;
932 u32 reserved:30;
933 } mfi_capabilities;
934 u32 reg;
935} MFI_CAPABILITIES;
936
923struct megasas_init_frame { 937struct megasas_init_frame {
924 938
925 u8 cmd; /*00h */ 939 u8 cmd; /*00h */
@@ -927,7 +941,7 @@ struct megasas_init_frame {
927 u8 cmd_status; /*02h */ 941 u8 cmd_status; /*02h */
928 942
929 u8 reserved_1; /*03h */ 943 u8 reserved_1; /*03h */
930 u32 reserved_2; /*04h */ 944 MFI_CAPABILITIES driver_operations; /*04h*/
931 945
932 u32 context; /*08h */ 946 u32 context; /*08h */
933 u32 pad_0; /*0Ch */ 947 u32 pad_0; /*0Ch */
@@ -1324,7 +1338,7 @@ struct megasas_instance {
1324 1338
1325 unsigned long base_addr; 1339 unsigned long base_addr;
1326 struct megasas_register_set __iomem *reg_set; 1340 struct megasas_register_set __iomem *reg_set;
1327 1341 u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
1328 struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; 1342 struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
1329 u8 ld_ids[MEGASAS_MAX_LD_IDS]; 1343 u8 ld_ids[MEGASAS_MAX_LD_IDS];
1330 s8 init_id; 1344 s8 init_id;
@@ -1393,6 +1407,7 @@ struct megasas_instance {
1393 long reset_flags; 1407 long reset_flags;
1394 struct mutex reset_mutex; 1408 struct mutex reset_mutex;
1395 int throttlequeuedepth; 1409 int throttlequeuedepth;
1410 u8 mask_interrupts;
1396}; 1411};
1397 1412
1398enum { 1413enum {
@@ -1408,8 +1423,8 @@ struct megasas_instance_template {
1408 void (*fire_cmd)(struct megasas_instance *, dma_addr_t, \ 1423 void (*fire_cmd)(struct megasas_instance *, dma_addr_t, \
1409 u32, struct megasas_register_set __iomem *); 1424 u32, struct megasas_register_set __iomem *);
1410 1425
1411 void (*enable_intr)(struct megasas_register_set __iomem *) ; 1426 void (*enable_intr)(struct megasas_instance *);
1412 void (*disable_intr)(struct megasas_register_set __iomem *); 1427 void (*disable_intr)(struct megasas_instance *);
1413 1428
1414 int (*clear_intr)(struct megasas_register_set __iomem *); 1429 int (*clear_intr)(struct megasas_register_set __iomem *);
1415 1430
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 63108d7849a4..11f1c940a2aa 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -244,8 +244,10 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd)
244 * @regs: MFI register set 244 * @regs: MFI register set
245 */ 245 */
246static inline void 246static inline void
247megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs) 247megasas_enable_intr_xscale(struct megasas_instance *instance)
248{ 248{
249 struct megasas_register_set __iomem *regs;
250 regs = instance->reg_set;
249 writel(0, &(regs)->outbound_intr_mask); 251 writel(0, &(regs)->outbound_intr_mask);
250 252
251 /* Dummy readl to force pci flush */ 253 /* Dummy readl to force pci flush */
@@ -257,9 +259,11 @@ megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
257 * @regs: MFI register set 259 * @regs: MFI register set
258 */ 260 */
259static inline void 261static inline void
260megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs) 262megasas_disable_intr_xscale(struct megasas_instance *instance)
261{ 263{
264 struct megasas_register_set __iomem *regs;
262 u32 mask = 0x1f; 265 u32 mask = 0x1f;
266 regs = instance->reg_set;
263 writel(mask, &regs->outbound_intr_mask); 267 writel(mask, &regs->outbound_intr_mask);
264 /* Dummy readl to force pci flush */ 268 /* Dummy readl to force pci flush */
265 readl(&regs->outbound_intr_mask); 269 readl(&regs->outbound_intr_mask);
@@ -413,8 +417,10 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
413 * @regs: MFI register set 417 * @regs: MFI register set
414 */ 418 */
415static inline void 419static inline void
416megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) 420megasas_enable_intr_ppc(struct megasas_instance *instance)
417{ 421{
422 struct megasas_register_set __iomem *regs;
423 regs = instance->reg_set;
418 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); 424 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
419 425
420 writel(~0x80000000, &(regs)->outbound_intr_mask); 426 writel(~0x80000000, &(regs)->outbound_intr_mask);
@@ -428,9 +434,11 @@ megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
428 * @regs: MFI register set 434 * @regs: MFI register set
429 */ 435 */
430static inline void 436static inline void
431megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs) 437megasas_disable_intr_ppc(struct megasas_instance *instance)
432{ 438{
439 struct megasas_register_set __iomem *regs;
433 u32 mask = 0xFFFFFFFF; 440 u32 mask = 0xFFFFFFFF;
441 regs = instance->reg_set;
434 writel(mask, &regs->outbound_intr_mask); 442 writel(mask, &regs->outbound_intr_mask);
435 /* Dummy readl to force pci flush */ 443 /* Dummy readl to force pci flush */
436 readl(&regs->outbound_intr_mask); 444 readl(&regs->outbound_intr_mask);
@@ -531,8 +539,10 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
531 * @regs: MFI register set 539 * @regs: MFI register set
532 */ 540 */
533static inline void 541static inline void
534megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs) 542megasas_enable_intr_skinny(struct megasas_instance *instance)
535{ 543{
544 struct megasas_register_set __iomem *regs;
545 regs = instance->reg_set;
536 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask); 546 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
537 547
538 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask); 548 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
@@ -546,9 +556,11 @@ megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
546 * @regs: MFI register set 556 * @regs: MFI register set
547 */ 557 */
548static inline void 558static inline void
549megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs) 559megasas_disable_intr_skinny(struct megasas_instance *instance)
550{ 560{
561 struct megasas_register_set __iomem *regs;
551 u32 mask = 0xFFFFFFFF; 562 u32 mask = 0xFFFFFFFF;
563 regs = instance->reg_set;
552 writel(mask, &regs->outbound_intr_mask); 564 writel(mask, &regs->outbound_intr_mask);
553 /* Dummy readl to force pci flush */ 565 /* Dummy readl to force pci flush */
554 readl(&regs->outbound_intr_mask); 566 readl(&regs->outbound_intr_mask);
@@ -666,8 +678,10 @@ static struct megasas_instance_template megasas_instance_template_skinny = {
666 * @regs: MFI register set 678 * @regs: MFI register set
667 */ 679 */
668static inline void 680static inline void
669megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs) 681megasas_enable_intr_gen2(struct megasas_instance *instance)
670{ 682{
683 struct megasas_register_set __iomem *regs;
684 regs = instance->reg_set;
671 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); 685 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
672 686
673 /* write ~0x00000005 (4 & 1) to the intr mask*/ 687 /* write ~0x00000005 (4 & 1) to the intr mask*/
@@ -682,9 +696,11 @@ megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs)
682 * @regs: MFI register set 696 * @regs: MFI register set
683 */ 697 */
684static inline void 698static inline void
685megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs) 699megasas_disable_intr_gen2(struct megasas_instance *instance)
686{ 700{
701 struct megasas_register_set __iomem *regs;
687 u32 mask = 0xFFFFFFFF; 702 u32 mask = 0xFFFFFFFF;
703 regs = instance->reg_set;
688 writel(mask, &regs->outbound_intr_mask); 704 writel(mask, &regs->outbound_intr_mask);
689 /* Dummy readl to force pci flush */ 705 /* Dummy readl to force pci flush */
690 readl(&regs->outbound_intr_mask); 706 readl(&regs->outbound_intr_mask);
@@ -1707,7 +1723,7 @@ void megasas_do_ocr(struct megasas_instance *instance)
1707 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) { 1723 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
1708 *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN; 1724 *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN;
1709 } 1725 }
1710 instance->instancet->disable_intr(instance->reg_set); 1726 instance->instancet->disable_intr(instance);
1711 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; 1727 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
1712 instance->issuepend_done = 0; 1728 instance->issuepend_done = 0;
1713 1729
@@ -2490,7 +2506,7 @@ process_fw_state_change_wq(struct work_struct *work)
2490 printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault" 2506 printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
2491 "state, restarting it...\n"); 2507 "state, restarting it...\n");
2492 2508
2493 instance->instancet->disable_intr(instance->reg_set); 2509 instance->instancet->disable_intr(instance);
2494 atomic_set(&instance->fw_outstanding, 0); 2510 atomic_set(&instance->fw_outstanding, 0);
2495 2511
2496 atomic_set(&instance->fw_reset_no_pci_access, 1); 2512 atomic_set(&instance->fw_reset_no_pci_access, 1);
@@ -2531,7 +2547,7 @@ process_fw_state_change_wq(struct work_struct *work)
2531 spin_lock_irqsave(&instance->hba_lock, flags); 2547 spin_lock_irqsave(&instance->hba_lock, flags);
2532 instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 2548 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2533 spin_unlock_irqrestore(&instance->hba_lock, flags); 2549 spin_unlock_irqrestore(&instance->hba_lock, flags);
2534 instance->instancet->enable_intr(instance->reg_set); 2550 instance->instancet->enable_intr(instance);
2535 2551
2536 megasas_issue_pending_cmds_again(instance); 2552 megasas_issue_pending_cmds_again(instance);
2537 instance->issuepend_done = 1; 2553 instance->issuepend_done = 1;
@@ -2594,7 +2610,7 @@ megasas_deplete_reply_queue(struct megasas_instance *instance,
2594 } 2610 }
2595 2611
2596 2612
2597 instance->instancet->disable_intr(instance->reg_set); 2613 instance->instancet->disable_intr(instance);
2598 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; 2614 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
2599 instance->issuepend_done = 0; 2615 instance->issuepend_done = 0;
2600 2616
@@ -2728,7 +2744,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
2728 /* 2744 /*
2729 * Bring it to READY state; assuming max wait 10 secs 2745 * Bring it to READY state; assuming max wait 10 secs
2730 */ 2746 */
2731 instance->instancet->disable_intr(instance->reg_set); 2747 instance->instancet->disable_intr(instance);
2732 if ((instance->pdev->device == 2748 if ((instance->pdev->device ==
2733 PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 2749 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2734 (instance->pdev->device == 2750 (instance->pdev->device ==
@@ -3374,7 +3390,7 @@ megasas_issue_init_mfi(struct megasas_instance *instance)
3374 /* 3390 /*
3375 * disable the intr before firing the init frame to FW 3391 * disable the intr before firing the init frame to FW
3376 */ 3392 */
3377 instance->instancet->disable_intr(instance->reg_set); 3393 instance->instancet->disable_intr(instance);
3378 3394
3379 /* 3395 /*
3380 * Issue the init frame in polled mode 3396 * Issue the init frame in polled mode
@@ -3481,11 +3497,11 @@ static int megasas_init_fw(struct megasas_instance *instance)
3481{ 3497{
3482 u32 max_sectors_1; 3498 u32 max_sectors_1;
3483 u32 max_sectors_2; 3499 u32 max_sectors_2;
3484 u32 tmp_sectors, msix_enable; 3500 u32 tmp_sectors, msix_enable, scratch_pad_2;
3485 struct megasas_register_set __iomem *reg_set; 3501 struct megasas_register_set __iomem *reg_set;
3486 struct megasas_ctrl_info *ctrl_info; 3502 struct megasas_ctrl_info *ctrl_info;
3487 unsigned long bar_list; 3503 unsigned long bar_list;
3488 int i; 3504 int i, loop, fw_msix_count = 0;
3489 3505
3490 /* Find first memory bar */ 3506 /* Find first memory bar */
3491 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM); 3507 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
@@ -3537,21 +3553,49 @@ static int megasas_init_fw(struct megasas_instance *instance)
3537 if (megasas_transition_to_ready(instance, 0)) 3553 if (megasas_transition_to_ready(instance, 0))
3538 goto fail_ready_state; 3554 goto fail_ready_state;
3539 3555
3556 /*
3557 * MSI-X host index 0 is common for all adapter.
3558 * It is used for all MPT based Adapters.
3559 */
3560 instance->reply_post_host_index_addr[0] =
3561 (u32 *)((u8 *)instance->reg_set +
3562 MPI2_REPLY_POST_HOST_INDEX_OFFSET);
3563
3540 /* Check if MSI-X is supported while in ready state */ 3564 /* Check if MSI-X is supported while in ready state */
3541 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & 3565 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
3542 0x4000000) >> 0x1a; 3566 0x4000000) >> 0x1a;
3543 if (msix_enable && !msix_disable) { 3567 if (msix_enable && !msix_disable) {
3568 scratch_pad_2 = readl
3569 (&instance->reg_set->outbound_scratch_pad_2);
3544 /* Check max MSI-X vectors */ 3570 /* Check max MSI-X vectors */
3545 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 3571 if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) {
3546 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || 3572 instance->msix_vectors = (scratch_pad_2
3547 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) { 3573 & MR_MAX_REPLY_QUEUES_OFFSET) + 1;
3548 instance->msix_vectors = (readl(&instance->reg_set-> 3574 fw_msix_count = instance->msix_vectors;
3549 outbound_scratch_pad_2
3550 ) & 0x1F) + 1;
3551 if (msix_vectors) 3575 if (msix_vectors)
3552 instance->msix_vectors = 3576 instance->msix_vectors =
3553 min(msix_vectors, 3577 min(msix_vectors,
3554 instance->msix_vectors); 3578 instance->msix_vectors);
3579 } else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
3580 || (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
3581 /* Invader/Fury supports more than 8 MSI-X */
3582 instance->msix_vectors = ((scratch_pad_2
3583 & MR_MAX_REPLY_QUEUES_EXT_OFFSET)
3584 >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
3585 fw_msix_count = instance->msix_vectors;
3586 /* Save 1-15 reply post index address to local memory
3587 * Index 0 is already saved from reg offset
3588 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
3589 */
3590 for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
3591 instance->reply_post_host_index_addr[loop] =
3592 (u32 *)((u8 *)instance->reg_set +
3593 MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
3594 + (loop * 0x10));
3595 }
3596 if (msix_vectors)
3597 instance->msix_vectors = min(msix_vectors,
3598 instance->msix_vectors);
3555 } else 3599 } else
3556 instance->msix_vectors = 1; 3600 instance->msix_vectors = 1;
3557 /* Don't bother allocating more MSI-X vectors than cpus */ 3601 /* Don't bother allocating more MSI-X vectors than cpus */
@@ -3571,6 +3615,12 @@ static int megasas_init_fw(struct megasas_instance *instance)
3571 } 3615 }
3572 } else 3616 } else
3573 instance->msix_vectors = 0; 3617 instance->msix_vectors = 0;
3618
3619 dev_info(&instance->pdev->dev, "[scsi%d]: FW supports"
3620 "<%d> MSIX vector,Online CPUs: <%d>,"
3621 "Current MSIX <%d>\n", instance->host->host_no,
3622 fw_msix_count, (unsigned int)num_online_cpus(),
3623 instance->msix_vectors);
3574 } 3624 }
3575 3625
3576 /* Get operational params, sge flags, send init cmd to controller */ 3626 /* Get operational params, sge flags, send init cmd to controller */
@@ -4166,6 +4216,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
4166 if (megasas_init_fw(instance)) 4216 if (megasas_init_fw(instance))
4167 goto fail_init_mfi; 4217 goto fail_init_mfi;
4168 4218
4219retry_irq_register:
4169 /* 4220 /*
4170 * Register IRQ 4221 * Register IRQ
4171 */ 4222 */
@@ -4183,7 +4234,9 @@ static int megasas_probe_one(struct pci_dev *pdev,
4183 free_irq( 4234 free_irq(
4184 instance->msixentry[j].vector, 4235 instance->msixentry[j].vector,
4185 &instance->irq_context[j]); 4236 &instance->irq_context[j]);
4186 goto fail_irq; 4237 /* Retry irq register for IO_APIC */
4238 instance->msix_vectors = 0;
4239 goto retry_irq_register;
4187 } 4240 }
4188 } 4241 }
4189 } else { 4242 } else {
@@ -4197,7 +4250,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
4197 } 4250 }
4198 } 4251 }
4199 4252
4200 instance->instancet->enable_intr(instance->reg_set); 4253 instance->instancet->enable_intr(instance);
4201 4254
4202 /* 4255 /*
4203 * Store instance in PCI softstate 4256 * Store instance in PCI softstate
@@ -4237,7 +4290,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
4237 megasas_mgmt_info.max_index--; 4290 megasas_mgmt_info.max_index--;
4238 4291
4239 pci_set_drvdata(pdev, NULL); 4292 pci_set_drvdata(pdev, NULL);
4240 instance->instancet->disable_intr(instance->reg_set); 4293 instance->instancet->disable_intr(instance);
4241 if (instance->msix_vectors) 4294 if (instance->msix_vectors)
4242 for (i = 0 ; i < instance->msix_vectors; i++) 4295 for (i = 0 ; i < instance->msix_vectors; i++)
4243 free_irq(instance->msixentry[i].vector, 4296 free_irq(instance->msixentry[i].vector,
@@ -4387,7 +4440,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
4387 tasklet_kill(&instance->isr_tasklet); 4440 tasklet_kill(&instance->isr_tasklet);
4388 4441
4389 pci_set_drvdata(instance->pdev, instance); 4442 pci_set_drvdata(instance->pdev, instance);
4390 instance->instancet->disable_intr(instance->reg_set); 4443 instance->instancet->disable_intr(instance);
4391 4444
4392 if (instance->msix_vectors) 4445 if (instance->msix_vectors)
4393 for (i = 0 ; i < instance->msix_vectors; i++) 4446 for (i = 0 ; i < instance->msix_vectors; i++)
@@ -4512,7 +4565,7 @@ megasas_resume(struct pci_dev *pdev)
4512 } 4565 }
4513 } 4566 }
4514 4567
4515 instance->instancet->enable_intr(instance->reg_set); 4568 instance->instancet->enable_intr(instance);
4516 instance->unload = 0; 4569 instance->unload = 0;
4517 4570
4518 /* 4571 /*
@@ -4594,7 +4647,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
4594 4647
4595 pci_set_drvdata(instance->pdev, NULL); 4648 pci_set_drvdata(instance->pdev, NULL);
4596 4649
4597 instance->instancet->disable_intr(instance->reg_set); 4650 instance->instancet->disable_intr(instance);
4598 4651
4599 if (instance->msix_vectors) 4652 if (instance->msix_vectors)
4600 for (i = 0 ; i < instance->msix_vectors; i++) 4653 for (i = 0 ; i < instance->msix_vectors; i++)
@@ -4654,7 +4707,7 @@ static void megasas_shutdown(struct pci_dev *pdev)
4654 instance->unload = 1; 4707 instance->unload = 1;
4655 megasas_flush_cache(instance); 4708 megasas_flush_cache(instance);
4656 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); 4709 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
4657 instance->instancet->disable_intr(instance->reg_set); 4710 instance->instancet->disable_intr(instance);
4658 if (instance->msix_vectors) 4711 if (instance->msix_vectors)
4659 for (i = 0 ; i < instance->msix_vectors; i++) 4712 for (i = 0 ; i < instance->msix_vectors; i++)
4660 free_irq(instance->msixentry[i].vector, 4713 free_irq(instance->msixentry[i].vector,
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:
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index f68a3cd11d5d..004c18e408c1 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -43,7 +43,7 @@
43#define HOST_DIAG_WRITE_ENABLE 0x80 43#define HOST_DIAG_WRITE_ENABLE 0x80
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#define MAX_MSIX_QUEUES_FUSION 16 46#define MAX_MSIX_QUEUES_FUSION 128
47 47
48/* Invader defines */ 48/* Invader defines */
49#define MPI2_TYPE_CUDA 0x2 49#define MPI2_TYPE_CUDA 0x2
@@ -62,6 +62,9 @@
62#define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20 62#define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20
63#define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60 63#define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60
64 64
65#define MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C)
66#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C)
67
65/* 68/*
66 * Raid context flags 69 * Raid context flags
67 */ 70 */