aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorSumit.Saxena@avagotech.com <Sumit.Saxena@avagotech.com>2015-04-23 07:00:09 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-05-25 11:46:26 -0400
commitd3557fc8be11d25f316884581f487684f8e7dad3 (patch)
treefb25ea261e2c99e6910db0fac6cc8938668d4fb3 /drivers/scsi/megaraid
parentea47ebf15d68d616cf0daef31e7f694d11b59f7f (diff)
megaraid_sas : Add separate function for setting up IRQs
This patch will create separate functions for- 1) setting up IRQs for MSI-x interrupts 2) setting up IRQs for legacy interrupts 3) freeing up IRQs. and enable interrupts after adapter's initialization. The reason behind initialising adapter earlier is: by that time firmware is operational and can send interrupts, so better to use interrupt based interface to send internal DCMD to firmware instead of using polling method, since MFI frames' pool size is reduced and polling method does not free up MFI frame for fusion adapters, so sending more DCMDs with polled method may cause MFI frames's pool go out of frames and end up failing DCMD. Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com> Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c281
1 files changed, 135 insertions, 146 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 890637fdd61e..5be9ce45bde8 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4414,6 +4414,107 @@ fail_alloc_cmds:
4414 return 1; 4414 return 1;
4415} 4415}
4416 4416
4417/*
4418 * megasas_setup_irqs_msix - register legacy interrupts.
4419 * @instance: Adapter soft state
4420 *
4421 * Do not enable interrupt, only setup ISRs.
4422 *
4423 * Return 0 on success.
4424 */
4425static int
4426megasas_setup_irqs_ioapic(struct megasas_instance *instance)
4427{
4428 struct pci_dev *pdev;
4429
4430 pdev = instance->pdev;
4431 instance->irq_context[0].instance = instance;
4432 instance->irq_context[0].MSIxIndex = 0;
4433 if (request_irq(pdev->irq, instance->instancet->service_isr,
4434 IRQF_SHARED, "megasas", &instance->irq_context[0])) {
4435 dev_err(&instance->pdev->dev,
4436 "Failed to register IRQ from %s %d\n",
4437 __func__, __LINE__);
4438 return -1;
4439 }
4440 return 0;
4441}
4442
4443/**
4444 * megasas_setup_irqs_msix - register MSI-x interrupts.
4445 * @instance: Adapter soft state
4446 * @is_probe: Driver probe check
4447 *
4448 * Do not enable interrupt, only setup ISRs.
4449 *
4450 * Return 0 on success.
4451 */
4452static int
4453megasas_setup_irqs_msix(struct megasas_instance *instance, u8 is_probe)
4454{
4455 int i, j, cpu;
4456 struct pci_dev *pdev;
4457
4458 pdev = instance->pdev;
4459
4460 /* Try MSI-x */
4461 cpu = cpumask_first(cpu_online_mask);
4462 for (i = 0; i < instance->msix_vectors; i++) {
4463 instance->irq_context[i].instance = instance;
4464 instance->irq_context[i].MSIxIndex = i;
4465 if (request_irq(instance->msixentry[i].vector,
4466 instance->instancet->service_isr, 0, "megasas",
4467 &instance->irq_context[i])) {
4468 dev_err(&instance->pdev->dev,
4469 "Failed to register IRQ for vector %d.\n", i);
4470 for (j = 0; j < i; j++) {
4471 if (smp_affinity_enable)
4472 irq_set_affinity_hint(
4473 instance->msixentry[j].vector, NULL);
4474 free_irq(instance->msixentry[j].vector,
4475 &instance->irq_context[j]);
4476 }
4477 /* Retry irq register for IO_APIC*/
4478 instance->msix_vectors = 0;
4479 if (is_probe)
4480 return megasas_setup_irqs_ioapic(instance);
4481 else
4482 return -1;
4483 }
4484 if (smp_affinity_enable) {
4485 if (irq_set_affinity_hint(instance->msixentry[i].vector,
4486 get_cpu_mask(cpu)))
4487 dev_err(&instance->pdev->dev,
4488 "Failed to set affinity hint"
4489 " for cpu %d\n", cpu);
4490 cpu = cpumask_next(cpu, cpu_online_mask);
4491 }
4492 }
4493 return 0;
4494}
4495
4496/*
4497 * megasas_destroy_irqs- unregister interrupts.
4498 * @instance: Adapter soft state
4499 * return: void
4500 */
4501static void
4502megasas_destroy_irqs(struct megasas_instance *instance) {
4503
4504 int i;
4505
4506 if (instance->msix_vectors)
4507 for (i = 0; i < instance->msix_vectors; i++) {
4508 if (smp_affinity_enable)
4509 irq_set_affinity_hint(
4510 instance->msixentry[i].vector, NULL);
4511 free_irq(instance->msixentry[i].vector,
4512 &instance->irq_context[i]);
4513 }
4514 else
4515 free_irq(instance->pdev->irq, &instance->irq_context[0]);
4516}
4517
4417/** 4518/**
4418 * megasas_init_fw - Initializes the FW 4519 * megasas_init_fw - Initializes the FW
4419 * @instance: Adapter soft state 4520 * @instance: Adapter soft state
@@ -4552,11 +4653,16 @@ static int megasas_init_fw(struct megasas_instance *instance)
4552 else 4653 else
4553 instance->msix_vectors = 0; 4654 instance->msix_vectors = 0;
4554 4655
4555 dev_info(&instance->pdev->dev, "[scsi%d]: FW supports" 4656 dev_info(&instance->pdev->dev,
4556 "<%d> MSIX vector,Online CPUs: <%d>," 4657 "firmware supports msix\t: (%d)", fw_msix_count);
4557 "Current MSIX <%d>\n", instance->host->host_no, 4658 dev_info(&instance->pdev->dev,
4558 fw_msix_count, (unsigned int)num_online_cpus(), 4659 "current msix/online cpus\t: (%d/%d)\n",
4559 instance->msix_vectors); 4660 instance->msix_vectors, (unsigned int)num_online_cpus());
4661
4662 if (instance->msix_vectors ?
4663 megasas_setup_irqs_msix(instance, 1) :
4664 megasas_setup_irqs_ioapic(instance))
4665 goto fail_setup_irqs;
4560 } 4666 }
4561 4667
4562 instance->ctrl_info = kzalloc(sizeof(struct megasas_ctrl_info), 4668 instance->ctrl_info = kzalloc(sizeof(struct megasas_ctrl_info),
@@ -4573,6 +4679,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
4573 /* Get operational params, sge flags, send init cmd to controller */ 4679 /* Get operational params, sge flags, send init cmd to controller */
4574 if (instance->instancet->init_adapter(instance)) 4680 if (instance->instancet->init_adapter(instance))
4575 goto fail_init_adapter; 4681 goto fail_init_adapter;
4682 instance->instancet->enable_intr(instance);
4576 4683
4577 printk(KERN_ERR "megasas: INIT adapter done\n"); 4684 printk(KERN_ERR "megasas: INIT adapter done\n");
4578 4685
@@ -4584,7 +4691,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
4584 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); 4691 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
4585 if (megasas_get_pd_list(instance) < 0) { 4692 if (megasas_get_pd_list(instance) < 0) {
4586 printk(KERN_ERR "megasas: failed to get PD list\n"); 4693 printk(KERN_ERR "megasas: failed to get PD list\n");
4587 goto fail_init_adapter; 4694 goto fail_get_pd_list;
4588 } 4695 }
4589 4696
4590 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); 4697 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
@@ -4733,7 +4840,14 @@ static int megasas_init_fw(struct megasas_instance *instance)
4733 4840
4734 return 0; 4841 return 0;
4735 4842
4843fail_get_pd_list:
4844 instance->instancet->disable_intr(instance);
4736fail_init_adapter: 4845fail_init_adapter:
4846 megasas_destroy_irqs(instance);
4847fail_setup_irqs:
4848 if (instance->msix_vectors)
4849 pci_disable_msix(instance->pdev);
4850 instance->msix_vectors = 0;
4737fail_ready_state: 4851fail_ready_state:
4738 kfree(instance->ctrl_info); 4852 kfree(instance->ctrl_info);
4739 instance->ctrl_info = NULL; 4853 instance->ctrl_info = NULL;
@@ -5106,7 +5220,7 @@ fail_set_dma_mask:
5106static int megasas_probe_one(struct pci_dev *pdev, 5220static int megasas_probe_one(struct pci_dev *pdev,
5107 const struct pci_device_id *id) 5221 const struct pci_device_id *id)
5108{ 5222{
5109 int rval, pos, i, j, cpu; 5223 int rval, pos;
5110 struct Scsi_Host *host; 5224 struct Scsi_Host *host;
5111 struct megasas_instance *instance; 5225 struct megasas_instance *instance;
5112 u16 control = 0; 5226 u16 control = 0;
@@ -5315,55 +5429,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
5315 } 5429 }
5316 } 5430 }
5317 5431
5318retry_irq_register:
5319 /*
5320 * Register IRQ
5321 */
5322 if (instance->msix_vectors) {
5323 cpu = cpumask_first(cpu_online_mask);
5324 for (i = 0; i < instance->msix_vectors; i++) {
5325 instance->irq_context[i].instance = instance;
5326 instance->irq_context[i].MSIxIndex = i;
5327 if (request_irq(instance->msixentry[i].vector,
5328 instance->instancet->service_isr, 0,
5329 "megasas",
5330 &instance->irq_context[i])) {
5331 printk(KERN_DEBUG "megasas: Failed to "
5332 "register IRQ for vector %d.\n", i);
5333 for (j = 0; j < i; j++) {
5334 if (smp_affinity_enable)
5335 irq_set_affinity_hint(
5336 instance->msixentry[j].vector, NULL);
5337 free_irq(
5338 instance->msixentry[j].vector,
5339 &instance->irq_context[j]);
5340 }
5341 /* Retry irq register for IO_APIC */
5342 instance->msix_vectors = 0;
5343 goto retry_irq_register;
5344 }
5345 if (smp_affinity_enable) {
5346 if (irq_set_affinity_hint(instance->msixentry[i].vector,
5347 get_cpu_mask(cpu)))
5348 dev_err(&instance->pdev->dev,
5349 "Error setting affinity hint "
5350 "for cpu %d\n", cpu);
5351 cpu = cpumask_next(cpu, cpu_online_mask);
5352 }
5353 }
5354 } else {
5355 instance->irq_context[0].instance = instance;
5356 instance->irq_context[0].MSIxIndex = 0;
5357 if (request_irq(pdev->irq, instance->instancet->service_isr,
5358 IRQF_SHARED, "megasas",
5359 &instance->irq_context[0])) {
5360 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
5361 goto fail_irq;
5362 }
5363 }
5364
5365 instance->instancet->enable_intr(instance);
5366
5367 /* 5432 /*
5368 * Store instance in PCI softstate 5433 * Store instance in PCI softstate
5369 */ 5434 */
@@ -5410,17 +5475,8 @@ retry_irq_register:
5410 megasas_mgmt_info.max_index--; 5475 megasas_mgmt_info.max_index--;
5411 5476
5412 instance->instancet->disable_intr(instance); 5477 instance->instancet->disable_intr(instance);
5413 if (instance->msix_vectors) 5478 megasas_destroy_irqs(instance);
5414 for (i = 0; i < instance->msix_vectors; i++) { 5479
5415 if (smp_affinity_enable)
5416 irq_set_affinity_hint(
5417 instance->msixentry[i].vector, NULL);
5418 free_irq(instance->msixentry[i].vector,
5419 &instance->irq_context[i]);
5420 }
5421 else
5422 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5423fail_irq:
5424 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || 5480 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
5425 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) || 5481 (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) ||
5426 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || 5482 (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
@@ -5428,9 +5484,9 @@ fail_irq:
5428 megasas_release_fusion(instance); 5484 megasas_release_fusion(instance);
5429 else 5485 else
5430 megasas_release_mfi(instance); 5486 megasas_release_mfi(instance);
5431 fail_init_mfi:
5432 if (instance->msix_vectors) 5487 if (instance->msix_vectors)
5433 pci_disable_msix(instance->pdev); 5488 pci_disable_msix(instance->pdev);
5489fail_init_mfi:
5434 fail_alloc_dma_buf: 5490 fail_alloc_dma_buf:
5435 if (instance->evt_detail) 5491 if (instance->evt_detail)
5436 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), 5492 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
@@ -5558,7 +5614,6 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
5558{ 5614{
5559 struct Scsi_Host *host; 5615 struct Scsi_Host *host;
5560 struct megasas_instance *instance; 5616 struct megasas_instance *instance;
5561 int i;
5562 5617
5563 instance = pci_get_drvdata(pdev); 5618 instance = pci_get_drvdata(pdev);
5564 host = instance->host; 5619 host = instance->host;
@@ -5583,16 +5638,8 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
5583 pci_set_drvdata(instance->pdev, instance); 5638 pci_set_drvdata(instance->pdev, instance);
5584 instance->instancet->disable_intr(instance); 5639 instance->instancet->disable_intr(instance);
5585 5640
5586 if (instance->msix_vectors) 5641 megasas_destroy_irqs(instance);
5587 for (i = 0; i < instance->msix_vectors; i++) { 5642
5588 if (smp_affinity_enable)
5589 irq_set_affinity_hint(
5590 instance->msixentry[i].vector, NULL);
5591 free_irq(instance->msixentry[i].vector,
5592 &instance->irq_context[i]);
5593 }
5594 else
5595 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5596 if (instance->msix_vectors) 5643 if (instance->msix_vectors)
5597 pci_disable_msix(instance->pdev); 5644 pci_disable_msix(instance->pdev);
5598 5645
@@ -5611,7 +5658,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
5611static int 5658static int
5612megasas_resume(struct pci_dev *pdev) 5659megasas_resume(struct pci_dev *pdev)
5613{ 5660{
5614 int rval, i, j, cpu; 5661 int rval;
5615 struct Scsi_Host *host; 5662 struct Scsi_Host *host;
5616 struct megasas_instance *instance; 5663 struct megasas_instance *instance;
5617 5664
@@ -5681,50 +5728,10 @@ megasas_resume(struct pci_dev *pdev)
5681 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, 5728 tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
5682 (unsigned long)instance); 5729 (unsigned long)instance);
5683 5730
5684 /* 5731 if (instance->msix_vectors ?
5685 * Register IRQ 5732 megasas_setup_irqs_msix(instance, 0) :
5686 */ 5733 megasas_setup_irqs_ioapic(instance))
5687 if (instance->msix_vectors) { 5734 goto fail_init_mfi;
5688 cpu = cpumask_first(cpu_online_mask);
5689 for (i = 0 ; i < instance->msix_vectors; i++) {
5690 instance->irq_context[i].instance = instance;
5691 instance->irq_context[i].MSIxIndex = i;
5692 if (request_irq(instance->msixentry[i].vector,
5693 instance->instancet->service_isr, 0,
5694 "megasas",
5695 &instance->irq_context[i])) {
5696 printk(KERN_DEBUG "megasas: Failed to "
5697 "register IRQ for vector %d.\n", i);
5698 for (j = 0; j < i; j++) {
5699 if (smp_affinity_enable)
5700 irq_set_affinity_hint(
5701 instance->msixentry[j].vector, NULL);
5702 free_irq(
5703 instance->msixentry[j].vector,
5704 &instance->irq_context[j]);
5705 }
5706 goto fail_irq;
5707 }
5708
5709 if (smp_affinity_enable) {
5710 if (irq_set_affinity_hint(instance->msixentry[i].vector,
5711 get_cpu_mask(cpu)))
5712 dev_err(&instance->pdev->dev, "Error "
5713 "setting affinity hint for cpu "
5714 "%d\n", cpu);
5715 cpu = cpumask_next(cpu, cpu_online_mask);
5716 }
5717 }
5718 } else {
5719 instance->irq_context[0].instance = instance;
5720 instance->irq_context[0].MSIxIndex = 0;
5721 if (request_irq(pdev->irq, instance->instancet->service_isr,
5722 IRQF_SHARED, "megasas",
5723 &instance->irq_context[0])) {
5724 printk(KERN_DEBUG "megasas: Failed to register IRQ\n");
5725 goto fail_irq;
5726 }
5727 }
5728 5735
5729 /* Re-launch SR-IOV heartbeat timer */ 5736 /* Re-launch SR-IOV heartbeat timer */
5730 if (instance->requestorId) { 5737 if (instance->requestorId) {
@@ -5748,7 +5755,6 @@ megasas_resume(struct pci_dev *pdev)
5748 5755
5749 return 0; 5756 return 0;
5750 5757
5751fail_irq:
5752fail_init_mfi: 5758fail_init_mfi:
5753 if (instance->evt_detail) 5759 if (instance->evt_detail)
5754 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), 5760 pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
@@ -5829,16 +5835,8 @@ static void megasas_detach_one(struct pci_dev *pdev)
5829 5835
5830 instance->instancet->disable_intr(instance); 5836 instance->instancet->disable_intr(instance);
5831 5837
5832 if (instance->msix_vectors) 5838 megasas_destroy_irqs(instance);
5833 for (i = 0; i < instance->msix_vectors; i++) { 5839
5834 if (smp_affinity_enable)
5835 irq_set_affinity_hint(
5836 instance->msixentry[i].vector, NULL);
5837 free_irq(instance->msixentry[i].vector,
5838 &instance->irq_context[i]);
5839 }
5840 else
5841 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5842 if (instance->msix_vectors) 5840 if (instance->msix_vectors)
5843 pci_disable_msix(instance->pdev); 5841 pci_disable_msix(instance->pdev);
5844 5842
@@ -5912,23 +5910,14 @@ static void megasas_detach_one(struct pci_dev *pdev)
5912 */ 5910 */
5913static void megasas_shutdown(struct pci_dev *pdev) 5911static void megasas_shutdown(struct pci_dev *pdev)
5914{ 5912{
5915 int i;
5916 struct megasas_instance *instance = pci_get_drvdata(pdev); 5913 struct megasas_instance *instance = pci_get_drvdata(pdev);
5917 5914
5918 instance->unload = 1; 5915 instance->unload = 1;
5919 megasas_flush_cache(instance); 5916 megasas_flush_cache(instance);
5920 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); 5917 megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
5921 instance->instancet->disable_intr(instance); 5918 instance->instancet->disable_intr(instance);
5922 if (instance->msix_vectors) 5919 megasas_destroy_irqs(instance);
5923 for (i = 0; i < instance->msix_vectors; i++) { 5920
5924 if (smp_affinity_enable)
5925 irq_set_affinity_hint(
5926 instance->msixentry[i].vector, NULL);
5927 free_irq(instance->msixentry[i].vector,
5928 &instance->irq_context[i]);
5929 }
5930 else
5931 free_irq(instance->pdev->irq, &instance->irq_context[0]);
5932 if (instance->msix_vectors) 5921 if (instance->msix_vectors)
5933 pci_disable_msix(instance->pdev); 5922 pci_disable_msix(instance->pdev);
5934} 5923}