summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhijeet Joglekar <abjoglek@cisco.com>2009-11-03 11:45:37 -0800
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 12:00:52 -0600
commit2e76f7670b33a3b0bdf015ed1459e4b417a40ce0 (patch)
tree6a361c53f41f848179fd8196d53ccfaeb6dcc32b
parent65d430fa99cbd0e88d09a3343f697c51fc8a7009 (diff)
downloadkernel-common-2e76f7670b33a3b0bdf015ed1459e4b417a40ce0.tar.gz
kernel-common-2e76f7670b33a3b0bdf015ed1459e4b417a40ce0.tar.bz2
kernel-common-2e76f7670b33a3b0bdf015ed1459e4b417a40ce0.zip
[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>
-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,
goto err_out_dev_close;
}
- err = fnic_request_intr(fnic);
- if (err) {
- shost_printk(KERN_ERR, fnic->lport->host,
- "Unable to request irq.\n");
- goto err_out_clear_intr;
- }
-
err = fnic_alloc_vnic_resources(fnic);
if (err) {
shost_printk(KERN_ERR, fnic->lport->host,
"Failed to alloc vNIC resources, "
"aborting.\n");
- goto err_out_free_intr;
+ goto err_out_clear_intr;
}
@@ -729,6 +722,14 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
fc_fabric_login(lp);
vnic_dev_enable(fnic->vdev);
+
+ err = fnic_request_intr(fnic);
+ if (err) {
+ shost_printk(KERN_ERR, fnic->lport->host,
+ "Unable to request irq.\n");
+ goto err_out_free_exch_mgr;
+ }
+
for (i = 0; i < fnic->intr_count; i++)
vnic_intr_unmask(&fnic->intr[i]);
@@ -753,8 +754,6 @@ err_out_free_ioreq_pool:
mempool_destroy(fnic->io_req_pool);
err_out_free_resources:
fnic_free_vnic_resources(fnic);
-err_out_free_intr:
- fnic_free_intr(fnic);
err_out_clear_intr:
fnic_clear_intr_mode(fnic);
err_out_dev_close:
@@ -828,8 +827,8 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
scsi_remove_host(fnic->lport->host);
fc_exch_mgr_free(fnic->lport);
vnic_dev_notify_unset(fnic->vdev);
- fnic_free_vnic_resources(fnic);
fnic_free_intr(fnic);
+ fnic_free_vnic_resources(fnic);
fnic_clear_intr_mode(fnic);
vnic_dev_close(fnic->vdev);
vnic_dev_unregister(fnic->vdev);