aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authoradam radford <aradford@gmail.com>2011-10-08 21:15:13 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-16 12:21:36 -0400
commitc8e858fe72230dd2ad07abcbec7c9f201672a8b4 (patch)
tree27935fbc43a1be44b700a39743bc405cab1313c0 /drivers/scsi
parent36807e6799dcd8f961137b74c7edce10c6fcb1d2 (diff)
[SCSI] megaraid_sas: Add multiple MSI-X vector/multiple reply queue support
Signed-off-by: Adam Radford <aradford@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h11
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c156
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c65
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.h3
4 files changed, 176 insertions, 59 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 6b3562554937..9ffb92daa58b 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -757,6 +757,7 @@ struct megasas_ctrl_info {
757#define MEGASAS_INT_CMDS 32 757#define MEGASAS_INT_CMDS 32
758#define MEGASAS_SKINNY_INT_CMDS 5 758#define MEGASAS_SKINNY_INT_CMDS 5
759 759
760#define MEGASAS_MAX_MSIX_QUEUES 16
760/* 761/*
761 * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit 762 * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
762 * SGLs based on the size of dma_addr_t 763 * SGLs based on the size of dma_addr_t
@@ -1278,6 +1279,11 @@ struct megasas_aen_event {
1278 struct megasas_instance *instance; 1279 struct megasas_instance *instance;
1279}; 1280};
1280 1281
1282struct megasas_irq_context {
1283 struct megasas_instance *instance;
1284 u32 MSIxIndex;
1285};
1286
1281struct megasas_instance { 1287struct megasas_instance {
1282 1288
1283 u32 *producer; 1289 u32 *producer;
@@ -1351,8 +1357,9 @@ struct megasas_instance {
1351 1357
1352 /* Ptr to hba specific information */ 1358 /* Ptr to hba specific information */
1353 void *ctrl_context; 1359 void *ctrl_context;
1354 u8 msi_flag; 1360 unsigned int msix_vectors;
1355 struct msix_entry msixentry; 1361 struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES];
1362 struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
1356 u64 map_id; 1363 u64 map_id;
1357 struct megasas_cmd *map_update_cmd; 1364 struct megasas_cmd *map_update_cmd;
1358 unsigned long bar; 1365 unsigned long bar;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index f2cf768c896d..ec09d5c2ed90 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -2536,7 +2536,7 @@ megasas_deplete_reply_queue(struct megasas_instance *instance,
2536 instance->reg_set) 2536 instance->reg_set)
2537 ) == 0) { 2537 ) == 0) {
2538 /* Hardware may not set outbound_intr_status in MSI-X mode */ 2538 /* Hardware may not set outbound_intr_status in MSI-X mode */
2539 if (!instance->msi_flag) 2539 if (!instance->msix_vectors)
2540 return IRQ_NONE; 2540 return IRQ_NONE;
2541 } 2541 }
2542 2542
@@ -2594,16 +2594,14 @@ megasas_deplete_reply_queue(struct megasas_instance *instance,
2594 */ 2594 */
2595static irqreturn_t megasas_isr(int irq, void *devp) 2595static irqreturn_t megasas_isr(int irq, void *devp)
2596{ 2596{
2597 struct megasas_instance *instance; 2597 struct megasas_irq_context *irq_context = devp;
2598 struct megasas_instance *instance = irq_context->instance;
2598 unsigned long flags; 2599 unsigned long flags;
2599 irqreturn_t rc; 2600 irqreturn_t rc;
2600 2601
2601 if (atomic_read( 2602 if (atomic_read(&instance->fw_reset_no_pci_access))
2602 &(((struct megasas_instance *)devp)->fw_reset_no_pci_access)))
2603 return IRQ_HANDLED; 2603 return IRQ_HANDLED;
2604 2604
2605 instance = (struct megasas_instance *)devp;
2606
2607 spin_lock_irqsave(&instance->hba_lock, flags); 2605 spin_lock_irqsave(&instance->hba_lock, flags);
2608 rc = megasas_deplete_reply_queue(instance, DID_OK); 2606 rc = megasas_deplete_reply_queue(instance, DID_OK);
2609 spin_unlock_irqrestore(&instance->hba_lock, flags); 2607 spin_unlock_irqrestore(&instance->hba_lock, flags);
@@ -3488,6 +3486,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
3488 struct megasas_register_set __iomem *reg_set; 3486 struct megasas_register_set __iomem *reg_set;
3489 struct megasas_ctrl_info *ctrl_info; 3487 struct megasas_ctrl_info *ctrl_info;
3490 unsigned long bar_list; 3488 unsigned long bar_list;
3489 int i;
3491 3490
3492 /* Find first memory bar */ 3491 /* Find first memory bar */
3493 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM); 3492 bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
@@ -3541,9 +3540,33 @@ static int megasas_init_fw(struct megasas_instance *instance)
3541 /* Check if MSI-X is supported while in ready state */ 3540 /* Check if MSI-X is supported while in ready state */
3542 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & 3541 msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
3543 0x4000000) >> 0x1a; 3542 0x4000000) >> 0x1a;
3544 if (msix_enable && !msix_disable && 3543 if (msix_enable && !msix_disable) {
3545 !pci_enable_msix(instance->pdev, &instance->msixentry, 1)) 3544 /* Check max MSI-X vectors */
3546 instance->msi_flag = 1; 3545 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
3546 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) {
3547 instance->msix_vectors = (readl(&instance->reg_set->
3548 outbound_scratch_pad_2
3549 ) & 0x1F) + 1;
3550 } else
3551 instance->msix_vectors = 1;
3552 /* Don't bother allocating more MSI-X vectors than cpus */
3553 instance->msix_vectors = min(instance->msix_vectors,
3554 (unsigned int)num_online_cpus());
3555 for (i = 0; i < instance->msix_vectors; i++)
3556 instance->msixentry[i].entry = i;
3557 i = pci_enable_msix(instance->pdev, instance->msixentry,
3558 instance->msix_vectors);
3559 if (i >= 0) {
3560 if (i) {
3561 if (!pci_enable_msix(instance->pdev,
3562 instance->msixentry, i))
3563 instance->msix_vectors = i;
3564 else
3565 instance->msix_vectors = 0;
3566 }
3567 } else
3568 instance->msix_vectors = 0;
3569 }
3547 3570
3548 /* Get operational params, sge flags, send init cmd to controller */ 3571 /* Get operational params, sge flags, send init cmd to controller */
3549 if (instance->instancet->init_adapter(instance)) 3572 if (instance->instancet->init_adapter(instance))
@@ -3958,7 +3981,7 @@ fail_set_dma_mask:
3958static int __devinit 3981static int __devinit
3959megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) 3982megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
3960{ 3983{
3961 int rval, pos; 3984 int rval, pos, i, j;
3962 struct Scsi_Host *host; 3985 struct Scsi_Host *host;
3963 struct megasas_instance *instance; 3986 struct megasas_instance *instance;
3964 u16 control = 0; 3987 u16 control = 0;
@@ -4126,11 +4149,32 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
4126 /* 4149 /*
4127 * Register IRQ 4150 * Register IRQ
4128 */ 4151 */
4129 if (request_irq(instance->msi_flag ? instance->msixentry.vector : 4152 if (instance->msix_vectors) {
4130 pdev->irq, instance->instancet->service_isr, 4153 for (i = 0 ; i < instance->msix_vectors; i++) {
4131 IRQF_SHARED, "megasas", instance)) { 4154 instance->irq_context[i].instance = instance;
4132 printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); 4155 instance->irq_context[i].MSIxIndex = i;
4133 goto fail_irq; 4156 if (request_irq(instance->msixentry[i].vector,
4157 instance->instancet->service_isr, 0,
4158 "megasas",
4159 &instance->irq_context[i])) {
4160 printk(KERN_DEBUG "megasas: Failed to "
4161 "register IRQ for vector %d.\n", i);
4162 for (j = 0 ; j < i ; j++)
4163 free_irq(
4164 instance->msixentry[j].vector,
4165 &instance->irq_context[j]);
4166 goto fail_irq;
4167 }
4168 }
4169 } else {
4170 instance->irq_context[0].instance = instance;
4171 instance->irq_context[0].MSIxIndex = 0;
4172 if (request_irq(pdev->irq, instance->instancet->service_isr,
4173 IRQF_SHARED, "megasas",
4174 &instance->irq_context[0])) {
4175 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
4176 goto fail_irq;
4177 }
4134 } 4178 }
4135 4179
4136 instance->instancet->enable_intr(instance->reg_set); 4180 instance->instancet->enable_intr(instance->reg_set);
@@ -4174,8 +4218,12 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
4174 4218
4175 pci_set_drvdata(pdev, NULL); 4219 pci_set_drvdata(pdev, NULL);
4176 instance->instancet->disable_intr(instance->reg_set); 4220 instance->instancet->disable_intr(instance->reg_set);
4177 free_irq(instance->msi_flag ? instance->msixentry.vector : 4221 if (instance->msix_vectors)
4178 instance->pdev->irq, instance); 4222 for (i = 0 ; i < instance->msix_vectors; i++)
4223 free_irq(instance->msixentry[i].vector,
4224 &instance->irq_context[i]);
4225 else
4226 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4179fail_irq: 4227fail_irq:
4180 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 4228 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
4181 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) 4229 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
@@ -4183,7 +4231,7 @@ fail_irq:
4183 else 4231 else
4184 megasas_release_mfi(instance); 4232 megasas_release_mfi(instance);
4185 fail_init_mfi: 4233 fail_init_mfi:
4186 if (instance->msi_flag) 4234 if (instance->msix_vectors)
4187 pci_disable_msix(instance->pdev); 4235 pci_disable_msix(instance->pdev);
4188 fail_alloc_dma_buf: 4236 fail_alloc_dma_buf:
4189 if (instance->evt_detail) 4237 if (instance->evt_detail)
@@ -4299,6 +4347,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
4299{ 4347{
4300 struct Scsi_Host *host; 4348 struct Scsi_Host *host;
4301 struct megasas_instance *instance; 4349 struct megasas_instance *instance;
4350 int i;
4302 4351
4303 instance = pci_get_drvdata(pdev); 4352 instance = pci_get_drvdata(pdev);
4304 host = instance->host; 4353 host = instance->host;
@@ -4322,9 +4371,14 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
4322 4371
4323 pci_set_drvdata(instance->pdev, instance); 4372 pci_set_drvdata(instance->pdev, instance);
4324 instance->instancet->disable_intr(instance->reg_set); 4373 instance->instancet->disable_intr(instance->reg_set);
4325 free_irq(instance->msi_flag ? instance->msixentry.vector : 4374
4326 instance->pdev->irq, instance); 4375 if (instance->msix_vectors)
4327 if (instance->msi_flag) 4376 for (i = 0 ; i < instance->msix_vectors; i++)
4377 free_irq(instance->msixentry[i].vector,
4378 &instance->irq_context[i]);
4379 else
4380 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4381 if (instance->msix_vectors)
4328 pci_disable_msix(instance->pdev); 4382 pci_disable_msix(instance->pdev);
4329 4383
4330 pci_save_state(pdev); 4384 pci_save_state(pdev);
@@ -4342,7 +4396,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
4342static int 4396static int
4343megasas_resume(struct pci_dev *pdev) 4397megasas_resume(struct pci_dev *pdev)
4344{ 4398{
4345 int rval; 4399 int rval, i, j;
4346 struct Scsi_Host *host; 4400 struct Scsi_Host *host;
4347 struct megasas_instance *instance; 4401 struct megasas_instance *instance;
4348 4402
@@ -4380,8 +4434,9 @@ megasas_resume(struct pci_dev *pdev)
4380 goto fail_ready_state; 4434 goto fail_ready_state;
4381 4435
4382 /* Now re-enable MSI-X */ 4436 /* Now re-enable MSI-X */
4383 if (instance->msi_flag) 4437 if (instance->msix_vectors)
4384 pci_enable_msix(instance->pdev, &instance->msixentry, 1); 4438 pci_enable_msix(instance->pdev, instance->msixentry,
4439 instance->msix_vectors);
4385 4440
4386 switch (instance->pdev->device) { 4441 switch (instance->pdev->device) {
4387 case PCI_DEVICE_ID_LSI_FUSION: 4442 case PCI_DEVICE_ID_LSI_FUSION:
@@ -4411,11 +4466,32 @@ megasas_resume(struct pci_dev *pdev)
4411 /* 4466 /*
4412 * Register IRQ 4467 * Register IRQ
4413 */ 4468 */
4414 if (request_irq(instance->msi_flag ? instance->msixentry.vector : 4469 if (instance->msix_vectors) {
4415 pdev->irq, instance->instancet->service_isr, 4470 for (i = 0 ; i < instance->msix_vectors; i++) {
4416 IRQF_SHARED, "megasas", instance)) { 4471 instance->irq_context[i].instance = instance;
4417 printk(KERN_ERR "megasas: Failed to register IRQ\n"); 4472 instance->irq_context[i].MSIxIndex = i;
4418 goto fail_irq; 4473 if (request_irq(instance->msixentry[i].vector,
4474 instance->instancet->service_isr, 0,
4475 "megasas",
4476 &instance->irq_context[i])) {
4477 printk(KERN_DEBUG "megasas: Failed to "
4478 "register IRQ for vector %d.\n", i);
4479 for (j = 0 ; j < i ; j++)
4480 free_irq(
4481 instance->msixentry[j].vector,
4482 &instance->irq_context[j]);
4483 goto fail_irq;
4484 }
4485 }
4486 } else {
4487 instance->irq_context[0].instance = instance;
4488 instance->irq_context[0].MSIxIndex = 0;
4489 if (request_irq(pdev->irq, instance->instancet->service_isr,
4490 IRQF_SHARED, "megasas",
4491 &instance->irq_context[0])) {
4492 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
4493 goto fail_irq;
4494 }
4419 } 4495 }
4420 4496
4421 instance->instancet->enable_intr(instance->reg_set); 4497 instance->instancet->enable_intr(instance->reg_set);
@@ -4512,9 +4588,13 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
4512 4588
4513 instance->instancet->disable_intr(instance->reg_set); 4589 instance->instancet->disable_intr(instance->reg_set);
4514 4590
4515 free_irq(instance->msi_flag ? instance->msixentry.vector : 4591 if (instance->msix_vectors)
4516 instance->pdev->irq, instance); 4592 for (i = 0 ; i < instance->msix_vectors; i++)
4517 if (instance->msi_flag) 4593 free_irq(instance->msixentry[i].vector,
4594 &instance->irq_context[i]);
4595 else
4596 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4597 if (instance->msix_vectors)
4518 pci_disable_msix(instance->pdev); 4598 pci_disable_msix(instance->pdev);
4519 4599
4520 switch (instance->pdev->device) { 4600 switch (instance->pdev->device) {
@@ -4560,14 +4640,20 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
4560 */ 4640 */
4561static void megasas_shutdown(struct pci_dev *pdev) 4641static void megasas_shutdown(struct pci_dev *pdev)
4562{ 4642{
4643 int i;
4563 struct megasas_instance *instance = pci_get_drvdata(pdev); 4644 struct megasas_instance *instance = pci_get_drvdata(pdev);
4645
4564 instance->unload = 1; 4646 instance->unload = 1;
4565 megasas_flush_cache(instance); 4647 megasas_flush_cache(instance);
4566 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); 4648 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
4567 instance->instancet->disable_intr(instance->reg_set); 4649 instance->instancet->disable_intr(instance->reg_set);
4568 free_irq(instance->msi_flag ? instance->msixentry.vector : 4650 if (instance->msix_vectors)
4569 instance->pdev->irq, instance); 4651 for (i = 0 ; i < instance->msix_vectors; i++)
4570 if (instance->msi_flag) 4652 free_irq(instance->msixentry[i].vector,
4653 &instance->irq_context[i]);
4654 else
4655 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4656 if (instance->msix_vectors)
4571 pci_disable_msix(instance->pdev); 4657 pci_disable_msix(instance->pdev);
4572} 4658}
4573 4659
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index ad6bd061a0f8..bfd87fab39aa 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -385,7 +385,7 @@ static int megasas_create_frame_pool_fusion(struct megasas_instance *instance)
385int 385int
386megasas_alloc_cmds_fusion(struct megasas_instance *instance) 386megasas_alloc_cmds_fusion(struct megasas_instance *instance)
387{ 387{
388 int i, j; 388 int i, j, count;
389 u32 max_cmd, io_frames_sz; 389 u32 max_cmd, io_frames_sz;
390 struct fusion_context *fusion; 390 struct fusion_context *fusion;
391 struct megasas_cmd_fusion *cmd; 391 struct megasas_cmd_fusion *cmd;
@@ -409,9 +409,10 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
409 goto fail_req_desc; 409 goto fail_req_desc;
410 } 410 }
411 411
412 count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
412 fusion->reply_frames_desc_pool = 413 fusion->reply_frames_desc_pool =
413 pci_pool_create("reply_frames pool", instance->pdev, 414 pci_pool_create("reply_frames pool", instance->pdev,
414 fusion->reply_alloc_sz, 16, 0); 415 fusion->reply_alloc_sz * count, 16, 0);
415 416
416 if (!fusion->reply_frames_desc_pool) { 417 if (!fusion->reply_frames_desc_pool) {
417 printk(KERN_ERR "megasas; Could not allocate memory for " 418 printk(KERN_ERR "megasas; Could not allocate memory for "
@@ -430,7 +431,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
430 } 431 }
431 432
432 reply_desc = fusion->reply_frames_desc; 433 reply_desc = fusion->reply_frames_desc;
433 for (i = 0; i < fusion->reply_q_depth; i++, reply_desc++) 434 for (i = 0; i < fusion->reply_q_depth * count; i++, reply_desc++)
434 reply_desc->Words = ULLONG_MAX; 435 reply_desc->Words = ULLONG_MAX;
435 436
436 io_frames_sz = fusion->io_frames_alloc_sz; 437 io_frames_sz = fusion->io_frames_alloc_sz;
@@ -633,7 +634,9 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
633 fusion->reply_frames_desc_phys; 634 fusion->reply_frames_desc_phys;
634 IOCInitMessage->SystemRequestFrameBaseAddress = 635 IOCInitMessage->SystemRequestFrameBaseAddress =
635 fusion->io_request_frames_phys; 636 fusion->io_request_frames_phys;
636 637 /* Set to 0 for none or 1 MSI-X vectors */
638 IOCInitMessage->HostMSIxVectors = (instance->msix_vectors > 0 ?
639 instance->msix_vectors : 0);
637 init_frame = (struct megasas_init_frame *)cmd->frame; 640 init_frame = (struct megasas_init_frame *)cmd->frame;
638 memset(init_frame, 0, MEGAMFI_FRAME_SIZE); 641 memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
639 642
@@ -877,7 +880,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
877 struct megasas_register_set __iomem *reg_set; 880 struct megasas_register_set __iomem *reg_set;
878 struct fusion_context *fusion; 881 struct fusion_context *fusion;
879 u32 max_cmd; 882 u32 max_cmd;
880 int i = 0; 883 int i = 0, count;
881 884
882 fusion = instance->ctrl_context; 885 fusion = instance->ctrl_context;
883 886
@@ -929,7 +932,9 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
929 (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE - 932 (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
930 sizeof(union MPI2_SGE_IO_UNION))/16; 933 sizeof(union MPI2_SGE_IO_UNION))/16;
931 934
932 fusion->last_reply_idx = 0; 935 count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
936 for (i = 0 ; i < count; i++)
937 fusion->last_reply_idx[i] = 0;
933 938
934 /* 939 /*
935 * Allocate memory for descriptors 940 * Allocate memory for descriptors
@@ -1421,6 +1426,12 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
1421 fp_possible = io_info.fpOkForIo; 1426 fp_possible = io_info.fpOkForIo;
1422 } 1427 }
1423 1428
1429 /* Use smp_processor_id() for now until cmd->request->cpu is CPU
1430 id by default, not CPU group id, otherwise all MSI-X queues won't
1431 be utilized */
1432 cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ?
1433 smp_processor_id() % instance->msix_vectors : 0;
1434
1424 if (fp_possible) { 1435 if (fp_possible) {
1425 megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp, 1436 megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
1426 local_map_ptr, start_lba_lo); 1437 local_map_ptr, start_lba_lo);
@@ -1691,7 +1702,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
1691 * Completes all commands that is in reply descriptor queue 1702 * Completes all commands that is in reply descriptor queue
1692 */ 1703 */
1693int 1704int
1694complete_cmd_fusion(struct megasas_instance *instance) 1705complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
1695{ 1706{
1696 union MPI2_REPLY_DESCRIPTORS_UNION *desc; 1707 union MPI2_REPLY_DESCRIPTORS_UNION *desc;
1697 struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *reply_desc; 1708 struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *reply_desc;
@@ -1711,7 +1722,9 @@ complete_cmd_fusion(struct megasas_instance *instance)
1711 return IRQ_HANDLED; 1722 return IRQ_HANDLED;
1712 1723
1713 desc = fusion->reply_frames_desc; 1724 desc = fusion->reply_frames_desc;
1714 desc += fusion->last_reply_idx; 1725 desc += ((MSIxIndex * fusion->reply_alloc_sz)/
1726 sizeof(union MPI2_REPLY_DESCRIPTORS_UNION)) +
1727 fusion->last_reply_idx[MSIxIndex];
1715 1728
1716 reply_desc = (struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc; 1729 reply_desc = (struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
1717 1730
@@ -1784,16 +1797,19 @@ complete_cmd_fusion(struct megasas_instance *instance)
1784 break; 1797 break;
1785 } 1798 }
1786 1799
1787 fusion->last_reply_idx++; 1800 fusion->last_reply_idx[MSIxIndex]++;
1788 if (fusion->last_reply_idx >= fusion->reply_q_depth) 1801 if (fusion->last_reply_idx[MSIxIndex] >=
1789 fusion->last_reply_idx = 0; 1802 fusion->reply_q_depth)
1803 fusion->last_reply_idx[MSIxIndex] = 0;
1790 1804
1791 desc->Words = ULLONG_MAX; 1805 desc->Words = ULLONG_MAX;
1792 num_completed++; 1806 num_completed++;
1793 1807
1794 /* Get the next reply descriptor */ 1808 /* Get the next reply descriptor */
1795 if (!fusion->last_reply_idx) 1809 if (!fusion->last_reply_idx[MSIxIndex])
1796 desc = fusion->reply_frames_desc; 1810 desc = fusion->reply_frames_desc +
1811 ((MSIxIndex * fusion->reply_alloc_sz)/
1812 sizeof(union MPI2_REPLY_DESCRIPTORS_UNION));
1797 else 1813 else
1798 desc++; 1814 desc++;
1799 1815
@@ -1813,7 +1829,7 @@ complete_cmd_fusion(struct megasas_instance *instance)
1813 return IRQ_NONE; 1829 return IRQ_NONE;
1814 1830
1815 wmb(); 1831 wmb();
1816 writel(fusion->last_reply_idx, 1832 writel((MSIxIndex << 24) | fusion->last_reply_idx[MSIxIndex],
1817 &instance->reg_set->reply_post_host_index); 1833 &instance->reg_set->reply_post_host_index);
1818 megasas_check_and_restore_queue_depth(instance); 1834 megasas_check_and_restore_queue_depth(instance);
1819 return IRQ_HANDLED; 1835 return IRQ_HANDLED;
@@ -1831,6 +1847,9 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
1831 struct megasas_instance *instance = 1847 struct megasas_instance *instance =
1832 (struct megasas_instance *)instance_addr; 1848 (struct megasas_instance *)instance_addr;
1833 unsigned long flags; 1849 unsigned long flags;
1850 u32 count, MSIxIndex;
1851
1852 count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
1834 1853
1835 /* If we have already declared adapter dead, donot complete cmds */ 1854 /* If we have already declared adapter dead, donot complete cmds */
1836 spin_lock_irqsave(&instance->hba_lock, flags); 1855 spin_lock_irqsave(&instance->hba_lock, flags);
@@ -1841,7 +1860,8 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
1841 spin_unlock_irqrestore(&instance->hba_lock, flags); 1860 spin_unlock_irqrestore(&instance->hba_lock, flags);
1842 1861
1843 spin_lock_irqsave(&instance->completion_lock, flags); 1862 spin_lock_irqsave(&instance->completion_lock, flags);
1844 complete_cmd_fusion(instance); 1863 for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++)
1864 complete_cmd_fusion(instance, MSIxIndex);
1845 spin_unlock_irqrestore(&instance->completion_lock, flags); 1865 spin_unlock_irqrestore(&instance->completion_lock, flags);
1846} 1866}
1847 1867
@@ -1850,10 +1870,11 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
1850 */ 1870 */
1851irqreturn_t megasas_isr_fusion(int irq, void *devp) 1871irqreturn_t megasas_isr_fusion(int irq, void *devp)
1852{ 1872{
1853 struct megasas_instance *instance = (struct megasas_instance *)devp; 1873 struct megasas_irq_context *irq_context = devp;
1874 struct megasas_instance *instance = irq_context->instance;
1854 u32 mfiStatus, fw_state; 1875 u32 mfiStatus, fw_state;
1855 1876
1856 if (!instance->msi_flag) { 1877 if (!instance->msix_vectors) {
1857 mfiStatus = instance->instancet->clear_intr(instance->reg_set); 1878 mfiStatus = instance->instancet->clear_intr(instance->reg_set);
1858 if (!mfiStatus) 1879 if (!mfiStatus)
1859 return IRQ_NONE; 1880 return IRQ_NONE;
@@ -1865,7 +1886,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp)
1865 return IRQ_HANDLED; 1886 return IRQ_HANDLED;
1866 } 1887 }
1867 1888
1868 if (!complete_cmd_fusion(instance)) { 1889 if (!complete_cmd_fusion(instance, irq_context->MSIxIndex)) {
1869 instance->instancet->clear_intr(instance->reg_set); 1890 instance->instancet->clear_intr(instance->reg_set);
1870 /* If we didn't complete any commands, check for FW fault */ 1891 /* If we didn't complete any commands, check for FW fault */
1871 fw_state = instance->instancet->read_fw_status_reg( 1892 fw_state = instance->instancet->read_fw_status_reg(
@@ -2081,14 +2102,16 @@ out:
2081 2102
2082void megasas_reset_reply_desc(struct megasas_instance *instance) 2103void megasas_reset_reply_desc(struct megasas_instance *instance)
2083{ 2104{
2084 int i; 2105 int i, count;
2085 struct fusion_context *fusion; 2106 struct fusion_context *fusion;
2086 union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc; 2107 union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc;
2087 2108
2088 fusion = instance->ctrl_context; 2109 fusion = instance->ctrl_context;
2089 fusion->last_reply_idx = 0; 2110 count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
2111 for (i = 0 ; i < count ; i++)
2112 fusion->last_reply_idx[i] = 0;
2090 reply_desc = fusion->reply_frames_desc; 2113 reply_desc = fusion->reply_frames_desc;
2091 for (i = 0 ; i < fusion->reply_q_depth; i++, reply_desc++) 2114 for (i = 0 ; i < fusion->reply_q_depth * count; i++, reply_desc++)
2092 reply_desc->Words = ULLONG_MAX; 2115 reply_desc->Words = ULLONG_MAX;
2093} 2116}
2094 2117
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 9556c08490b2..088c9f91da95 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -43,6 +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 47
47/* Invader defines */ 48/* Invader defines */
48#define MPI2_TYPE_CUDA 0x2 49#define MPI2_TYPE_CUDA 0x2
@@ -673,7 +674,7 @@ struct fusion_context {
673 union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc; 674 union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc;
674 struct dma_pool *reply_frames_desc_pool; 675 struct dma_pool *reply_frames_desc_pool;
675 676
676 u16 last_reply_idx; 677 u16 last_reply_idx[MAX_MSIX_QUEUES_FUSION];
677 678
678 u32 reply_q_depth; 679 u32 reply_q_depth;
679 u32 request_alloc_sz; 680 u32 request_alloc_sz;