summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2fc
diff options
context:
space:
mode:
authorBhanu Prakash Gollapudi <bprakash@broadcom.com>2011-08-31 00:54:52 +0200
committerJames Bottomley <JBottomley@Parallels.com>2011-09-17 16:05:33 +0200
commit013068fa6f65f7037adedc141fbd27afc99ab1bb (patch)
treeb2766fb68859ab509f2036d528af7dc85e774e45 /drivers/scsi/bnx2fc
parent[SCSI] bnx2fc: Avoid calling bnx2fc_if_destroy with unnecessary locks (diff)
downloadlinux-013068fa6f65f7037adedc141fbd27afc99ab1bb.tar.xz
linux-013068fa6f65f7037adedc141fbd27afc99ab1bb.zip
[SCSI] bnx2fc: Fix panic caused because of incorrect errror handling in create().
Driver incorrectly calls bnx2fc_interface_cleanup() when bnx2fc_if_create fails which accesses bad pointer. Handle bnx2fc_if_create failure by directly calling bnx2fc_net_cleanup. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index a5111f365f69..330f9f0e1937 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -1441,6 +1441,14 @@ free_blport:
return NULL;
}
+static void bnx2fc_net_cleanup(struct bnx2fc_interface *interface)
+{
+ /* Dont listen for Ethernet packets anymore */
+ __dev_remove_pack(&interface->fcoe_packet_type);
+ __dev_remove_pack(&interface->fip_packet_type);
+ synchronize_net();
+}
+
static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
{
struct fc_lport *lport = interface->ctlr.lp;
@@ -1453,10 +1461,7 @@ static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
/* Free existing transmit skbs */
fcoe_clean_pending_queue(lport);
- /* Dont listen for Ethernet packets anymore */
- __dev_remove_pack(&interface->fcoe_packet_type);
- __dev_remove_pack(&interface->fip_packet_type);
- synchronize_net();
+ bnx2fc_net_cleanup(interface);
bnx2fc_free_vport(hba, lport);
}
@@ -1991,7 +1996,6 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
if (!lport) {
printk(KERN_ERR PFX "Failed to create interface (%s)\n",
netdev->name);
- bnx2fc_interface_cleanup(interface);
rc = -EINVAL;
goto if_create_err;
}
@@ -2026,6 +2030,7 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode)
if_create_err:
destroy_workqueue(interface->timer_work_queue);
ifput_err:
+ bnx2fc_net_cleanup(interface);
bnx2fc_interface_put(interface);
netdev_err:
module_put(THIS_MODULE);