diff options
author | Bhanu Prakash Gollapudi <bprakash@broadcom.com> | 2011-08-30 18:54:52 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-09-17 10:05:33 -0400 |
commit | 013068fa6f65f7037adedc141fbd27afc99ab1bb (patch) | |
tree | b2766fb68859ab509f2036d528af7dc85e774e45 /drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |
parent | 0cbf32e1681d870632a1772601cbaadd996dc978 (diff) |
[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/bnx2fc_fcoe.c')
-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: | |||
1441 | return NULL; | 1441 | return NULL; |
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | static void bnx2fc_net_cleanup(struct bnx2fc_interface *interface) | ||
1445 | { | ||
1446 | /* Dont listen for Ethernet packets anymore */ | ||
1447 | __dev_remove_pack(&interface->fcoe_packet_type); | ||
1448 | __dev_remove_pack(&interface->fip_packet_type); | ||
1449 | synchronize_net(); | ||
1450 | } | ||
1451 | |||
1444 | static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface) | 1452 | static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface) |
1445 | { | 1453 | { |
1446 | struct fc_lport *lport = interface->ctlr.lp; | 1454 | struct fc_lport *lport = interface->ctlr.lp; |
@@ -1453,10 +1461,7 @@ static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface) | |||
1453 | /* Free existing transmit skbs */ | 1461 | /* Free existing transmit skbs */ |
1454 | fcoe_clean_pending_queue(lport); | 1462 | fcoe_clean_pending_queue(lport); |
1455 | 1463 | ||
1456 | /* Dont listen for Ethernet packets anymore */ | 1464 | bnx2fc_net_cleanup(interface); |
1457 | __dev_remove_pack(&interface->fcoe_packet_type); | ||
1458 | __dev_remove_pack(&interface->fip_packet_type); | ||
1459 | synchronize_net(); | ||
1460 | 1465 | ||
1461 | bnx2fc_free_vport(hba, lport); | 1466 | bnx2fc_free_vport(hba, lport); |
1462 | } | 1467 | } |
@@ -1991,7 +1996,6 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | |||
1991 | if (!lport) { | 1996 | if (!lport) { |
1992 | printk(KERN_ERR PFX "Failed to create interface (%s)\n", | 1997 | printk(KERN_ERR PFX "Failed to create interface (%s)\n", |
1993 | netdev->name); | 1998 | netdev->name); |
1994 | bnx2fc_interface_cleanup(interface); | ||
1995 | rc = -EINVAL; | 1999 | rc = -EINVAL; |
1996 | goto if_create_err; | 2000 | goto if_create_err; |
1997 | } | 2001 | } |
@@ -2026,6 +2030,7 @@ static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2026 | if_create_err: | 2030 | if_create_err: |
2027 | destroy_workqueue(interface->timer_work_queue); | 2031 | destroy_workqueue(interface->timer_work_queue); |
2028 | ifput_err: | 2032 | ifput_err: |
2033 | bnx2fc_net_cleanup(interface); | ||
2029 | bnx2fc_interface_put(interface); | 2034 | bnx2fc_interface_put(interface); |
2030 | netdev_err: | 2035 | netdev_err: |
2031 | module_put(THIS_MODULE); | 2036 | module_put(THIS_MODULE); |