aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}