aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fnic
diff options
context:
space:
mode:
authorAbhijeet Joglekar <abjoglek@cisco.com>2009-11-03 14:45:37 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:00:52 -0500
commit2e76f7670b33a3b0bdf015ed1459e4b417a40ce0 (patch)
tree6a361c53f41f848179fd8196d53ccfaeb6dcc32b /drivers/scsi/fnic
parent65d430fa99cbd0e88d09a3343f697c51fc8a7009 (diff)
[SCSI] fnic: Allocate OS interrupt resources just before enabling interrupts
The OS interrupt vectors were getting allocated before the interrupt resources were mapped from hardware. For Legacy interrupts, since they are shared with other devices, as soon as an interrupt is registered with the OS, it can fire while the fnic isr resource is still unmapped. This can cause crash because of access to unmapped resources. For MSIX and MSI, since interrupts are not shared with other devices, this problem didnt happen, because the interrupt is enabled as the last step before returning from _probe. For Legacy however, since the interrupt is shared, the handler can be called as soon as it is registered. Solution is to register interrupt handlers with OS as last step before enabling device interrupts. Signed-off-by: Abhijeet Joglekar <abjoglek@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fnic')
-rw-r--r--drivers/scsi/fnic/fnic_main.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index b0d425ab30ab..fc61f17025ce 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -572,19 +572,12 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
572 goto err_out_dev_close; 572 goto err_out_dev_close;
573 } 573 }
574 574
575 err = fnic_request_intr(fnic);
576 if (err) {
577 shost_printk(KERN_ERR, fnic->lport->host,
578 "Unable to request irq.\n");
579 goto err_out_clear_intr;
580 }
581
582 err = fnic_alloc_vnic_resources(fnic); 575 err = fnic_alloc_vnic_resources(fnic);
583 if (err) { 576 if (err) {
584 shost_printk(KERN_ERR, fnic->lport->host, 577 shost_printk(KERN_ERR, fnic->lport->host,
585 "Failed to alloc vNIC resources, " 578 "Failed to alloc vNIC resources, "
586 "aborting.\n"); 579 "aborting.\n");
587 goto err_out_free_intr; 580 goto err_out_clear_intr;
588 } 581 }
589 582
590 583
@@ -729,6 +722,14 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
729 fc_fabric_login(lp); 722 fc_fabric_login(lp);
730 723
731 vnic_dev_enable(fnic->vdev); 724 vnic_dev_enable(fnic->vdev);
725
726 err = fnic_request_intr(fnic);
727 if (err) {
728 shost_printk(KERN_ERR, fnic->lport->host,
729 "Unable to request irq.\n");
730 goto err_out_free_exch_mgr;
731 }
732
732 for (i = 0; i < fnic->intr_count; i++) 733 for (i = 0; i < fnic->intr_count; i++)
733 vnic_intr_unmask(&fnic->intr[i]); 734 vnic_intr_unmask(&fnic->intr[i]);
734 735
@@ -753,8 +754,6 @@ err_out_free_ioreq_pool:
753 mempool_destroy(fnic->io_req_pool); 754 mempool_destroy(fnic->io_req_pool);
754err_out_free_resources: 755err_out_free_resources:
755 fnic_free_vnic_resources(fnic); 756 fnic_free_vnic_resources(fnic);
756err_out_free_intr:
757 fnic_free_intr(fnic);
758err_out_clear_intr: 757err_out_clear_intr:
759 fnic_clear_intr_mode(fnic); 758 fnic_clear_intr_mode(fnic);
760err_out_dev_close: 759err_out_dev_close:
@@ -828,8 +827,8 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
828 scsi_remove_host(fnic->lport->host); 827 scsi_remove_host(fnic->lport->host);
829 fc_exch_mgr_free(fnic->lport); 828 fc_exch_mgr_free(fnic->lport);
830 vnic_dev_notify_unset(fnic->vdev); 829 vnic_dev_notify_unset(fnic->vdev);
831 fnic_free_vnic_resources(fnic);
832 fnic_free_intr(fnic); 830 fnic_free_intr(fnic);
831 fnic_free_vnic_resources(fnic);
833 fnic_clear_intr_mode(fnic); 832 fnic_clear_intr_mode(fnic);
834 vnic_dev_close(fnic->vdev); 833 vnic_dev_close(fnic->vdev);
835 vnic_dev_unregister(fnic->vdev); 834 vnic_dev_unregister(fnic->vdev);