diff options
author | Bhanu Prakash Gollapudi <bprakash@broadcom.com> | 2011-08-31 00:54:52 +0200 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-09-17 16:05:33 +0200 |
commit | 013068fa6f65f7037adedc141fbd27afc99ab1bb (patch) | |
tree | b2766fb68859ab509f2036d528af7dc85e774e45 /drivers/scsi/bnx2fc | |
parent | [SCSI] bnx2fc: Avoid calling bnx2fc_if_destroy with unnecessary locks (diff) | |
download | linux-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.c | 15 |
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); |