diff options
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 25 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 4 |
2 files changed, 24 insertions, 5 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 335e85192807..09a6a26282ac 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -411,20 +411,18 @@ out: | |||
411 | } | 411 | } |
412 | 412 | ||
413 | /** | 413 | /** |
414 | * fcoe_interface_cleanup() - Clean up a FCoE interface | 414 | * fcoe_interface_remove() - remove FCoE interface from netdev |
415 | * @fcoe: The FCoE interface to be cleaned up | 415 | * @fcoe: The FCoE interface to be cleaned up |
416 | * | 416 | * |
417 | * Caller must be holding the RTNL mutex | 417 | * Caller must be holding the RTNL mutex |
418 | */ | 418 | */ |
419 | static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | 419 | static void fcoe_interface_remove(struct fcoe_interface *fcoe) |
420 | { | 420 | { |
421 | struct net_device *netdev = fcoe->netdev; | 421 | struct net_device *netdev = fcoe->netdev; |
422 | struct fcoe_ctlr *fip = &fcoe->ctlr; | 422 | struct fcoe_ctlr *fip = &fcoe->ctlr; |
423 | u8 flogi_maddr[ETH_ALEN]; | 423 | u8 flogi_maddr[ETH_ALEN]; |
424 | const struct net_device_ops *ops; | 424 | const struct net_device_ops *ops; |
425 | 425 | ||
426 | rtnl_lock(); | ||
427 | |||
428 | /* | 426 | /* |
429 | * Don't listen for Ethernet packets anymore. | 427 | * Don't listen for Ethernet packets anymore. |
430 | * synchronize_net() ensures that the packet handlers are not running | 428 | * synchronize_net() ensures that the packet handlers are not running |
@@ -453,7 +451,22 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
453 | FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" | 451 | FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" |
454 | " specific feature for LLD.\n"); | 452 | " specific feature for LLD.\n"); |
455 | } | 453 | } |
454 | fcoe->removed = 1; | ||
455 | } | ||
456 | |||
457 | |||
458 | /** | ||
459 | * fcoe_interface_cleanup() - Clean up a FCoE interface | ||
460 | * @fcoe: The FCoE interface to be cleaned up | ||
461 | */ | ||
462 | static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | ||
463 | { | ||
464 | struct net_device *netdev = fcoe->netdev; | ||
465 | struct fcoe_ctlr *fip = &fcoe->ctlr; | ||
456 | 466 | ||
467 | rtnl_lock(); | ||
468 | if (!fcoe->removed) | ||
469 | fcoe_interface_remove(fcoe); | ||
457 | rtnl_unlock(); | 470 | rtnl_unlock(); |
458 | 471 | ||
459 | /* Release the self-reference taken during fcoe_interface_create() */ | 472 | /* Release the self-reference taken during fcoe_interface_create() */ |
@@ -941,6 +954,10 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
941 | rtnl_lock(); | 954 | rtnl_lock(); |
942 | if (!is_zero_ether_addr(port->data_src_addr)) | 955 | if (!is_zero_ether_addr(port->data_src_addr)) |
943 | dev_uc_del(netdev, port->data_src_addr); | 956 | dev_uc_del(netdev, port->data_src_addr); |
957 | if (lport->vport) | ||
958 | synchronize_net(); | ||
959 | else | ||
960 | fcoe_interface_remove(fcoe); | ||
944 | rtnl_unlock(); | 961 | rtnl_unlock(); |
945 | 962 | ||
946 | /* Free queued packets for the per-CPU receive threads */ | 963 | /* Free queued packets for the per-CPU receive threads */ |
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index 3c2733a12aa1..96ac938d39cc 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h | |||
@@ -71,7 +71,8 @@ do { \ | |||
71 | * @ctlr: The FCoE controller (for FIP) | 71 | * @ctlr: The FCoE controller (for FIP) |
72 | * @oem: The offload exchange manager for all local port | 72 | * @oem: The offload exchange manager for all local port |
73 | * instances associated with this port | 73 | * instances associated with this port |
74 | * This structure is 1:1 with a net devive. | 74 | * @removed: Indicates fcoe interface removed from net device |
75 | * This structure is 1:1 with a net device. | ||
75 | */ | 76 | */ |
76 | struct fcoe_interface { | 77 | struct fcoe_interface { |
77 | struct list_head list; | 78 | struct list_head list; |
@@ -81,6 +82,7 @@ struct fcoe_interface { | |||
81 | struct packet_type fip_packet_type; | 82 | struct packet_type fip_packet_type; |
82 | struct fcoe_ctlr ctlr; | 83 | struct fcoe_ctlr ctlr; |
83 | struct fc_exch_mgr *oem; | 84 | struct fc_exch_mgr *oem; |
85 | u8 removed; | ||
84 | }; | 86 | }; |
85 | 87 | ||
86 | #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) | 88 | #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) |