diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 43added0a17c..c9a0346e493a 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -616,9 +616,6 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
616 | /* Logout of the fabric */ | 616 | /* Logout of the fabric */ |
617 | fc_fabric_logoff(lport); | 617 | fc_fabric_logoff(lport); |
618 | 618 | ||
619 | /* Remove the instance from fcoe's list */ | ||
620 | fcoe_hostlist_remove(lport); | ||
621 | |||
622 | /* Cleanup the fc_lport */ | 619 | /* Cleanup the fc_lport */ |
623 | fc_lport_destroy(lport); | 620 | fc_lport_destroy(lport); |
624 | fc_fcp_destroy(lport); | 621 | fc_fcp_destroy(lport); |
@@ -757,11 +754,13 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | |||
757 | 754 | ||
758 | /* | 755 | /* |
759 | * fcoe_em_alloc() and fcoe_hostlist_add() both | 756 | * fcoe_em_alloc() and fcoe_hostlist_add() both |
760 | * need to be atomic under fcoe_hostlist_lock | 757 | * need to be atomic with respect to other changes to the hostlist |
761 | * since fcoe_em_alloc() looks for an existing EM | 758 | * since fcoe_em_alloc() looks for an existing EM |
762 | * instance on host list updated by fcoe_hostlist_add(). | 759 | * instance on host list updated by fcoe_hostlist_add(). |
760 | * | ||
761 | * This is currently handled through the fcoe_config_mutex begin held. | ||
763 | */ | 762 | */ |
764 | write_lock(&fcoe_hostlist_lock); | 763 | |
765 | /* lport exch manager allocation */ | 764 | /* lport exch manager allocation */ |
766 | rc = fcoe_em_config(lport); | 765 | rc = fcoe_em_config(lport); |
767 | if (rc) { | 766 | if (rc) { |
@@ -770,10 +769,6 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, | |||
770 | goto out_lp_destroy; | 769 | goto out_lp_destroy; |
771 | } | 770 | } |
772 | 771 | ||
773 | /* add to lports list */ | ||
774 | fcoe_hostlist_add(lport); | ||
775 | write_unlock(&fcoe_hostlist_lock); | ||
776 | |||
777 | dev_hold(netdev); | 772 | dev_hold(netdev); |
778 | fcoe_interface_get(fcoe); | 773 | fcoe_interface_get(fcoe); |
779 | return lport; | 774 | return lport; |
@@ -1713,6 +1708,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
1713 | rc = -ENODEV; | 1708 | rc = -ENODEV; |
1714 | goto out_putdev; | 1709 | goto out_putdev; |
1715 | } | 1710 | } |
1711 | /* Remove the instance from fcoe's list */ | ||
1712 | fcoe_hostlist_remove(lport); | ||
1716 | port = lport_priv(lport); | 1713 | port = lport_priv(lport); |
1717 | fcoe = port->fcoe; | 1714 | fcoe = port->fcoe; |
1718 | fcoe_if_destroy(lport); | 1715 | fcoe_if_destroy(lport); |
@@ -1782,6 +1779,9 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
1782 | /* Make this the "master" N_Port */ | 1779 | /* Make this the "master" N_Port */ |
1783 | fcoe->ctlr.lp = lport; | 1780 | fcoe->ctlr.lp = lport; |
1784 | 1781 | ||
1782 | /* add to lports list */ | ||
1783 | fcoe_hostlist_add(lport); | ||
1784 | |||
1785 | /* start FIP Discovery and FLOGI */ | 1785 | /* start FIP Discovery and FLOGI */ |
1786 | lport->boot_time = jiffies; | 1786 | lport->boot_time = jiffies; |
1787 | fc_fabric_login(lport); | 1787 | fc_fabric_login(lport); |
@@ -1954,8 +1954,6 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) | |||
1954 | * fcoe_hostlist_add() - Add a lport to lports list | 1954 | * fcoe_hostlist_add() - Add a lport to lports list |
1955 | * @lp: ptr to the fc_lport to be added | 1955 | * @lp: ptr to the fc_lport to be added |
1956 | * | 1956 | * |
1957 | * Called with write fcoe_hostlist_lock held. | ||
1958 | * | ||
1959 | * Returns: 0 for success | 1957 | * Returns: 0 for success |
1960 | */ | 1958 | */ |
1961 | int fcoe_hostlist_add(const struct fc_lport *lport) | 1959 | int fcoe_hostlist_add(const struct fc_lport *lport) |
@@ -1963,12 +1961,14 @@ int fcoe_hostlist_add(const struct fc_lport *lport) | |||
1963 | struct fcoe_interface *fcoe; | 1961 | struct fcoe_interface *fcoe; |
1964 | struct fcoe_port *port; | 1962 | struct fcoe_port *port; |
1965 | 1963 | ||
1964 | write_lock_bh(&fcoe_hostlist_lock); | ||
1966 | fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); | 1965 | fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); |
1967 | if (!fcoe) { | 1966 | if (!fcoe) { |
1968 | port = lport_priv(lport); | 1967 | port = lport_priv(lport); |
1969 | fcoe = port->fcoe; | 1968 | fcoe = port->fcoe; |
1970 | list_add_tail(&fcoe->list, &fcoe_hostlist); | 1969 | list_add_tail(&fcoe->list, &fcoe_hostlist); |
1971 | } | 1970 | } |
1971 | write_unlock_bh(&fcoe_hostlist_lock); | ||
1972 | return 0; | 1972 | return 0; |
1973 | } | 1973 | } |
1974 | 1974 | ||
@@ -2045,14 +2045,21 @@ static void __exit fcoe_exit(void) | |||
2045 | { | 2045 | { |
2046 | unsigned int cpu; | 2046 | unsigned int cpu; |
2047 | struct fcoe_interface *fcoe, *tmp; | 2047 | struct fcoe_interface *fcoe, *tmp; |
2048 | LIST_HEAD(local_list); | ||
2048 | 2049 | ||
2049 | mutex_lock(&fcoe_config_mutex); | 2050 | mutex_lock(&fcoe_config_mutex); |
2050 | 2051 | ||
2051 | fcoe_dev_cleanup(); | 2052 | fcoe_dev_cleanup(); |
2052 | 2053 | ||
2053 | /* releases the associated fcoe hosts */ | 2054 | /* releases the associated fcoe hosts */ |
2054 | list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) | 2055 | write_lock_bh(&fcoe_hostlist_lock); |
2056 | list_splice_init(&fcoe_hostlist, &local_list); | ||
2057 | write_unlock_bh(&fcoe_hostlist_lock); | ||
2058 | |||
2059 | list_for_each_entry_safe(fcoe, tmp, &local_list, list) { | ||
2060 | list_del(&fcoe->list); | ||
2055 | fcoe_if_destroy(fcoe->ctlr.lp); | 2061 | fcoe_if_destroy(fcoe->ctlr.lp); |
2062 | } | ||
2056 | 2063 | ||
2057 | unregister_hotcpu_notifier(&fcoe_cpu_notifier); | 2064 | unregister_hotcpu_notifier(&fcoe_cpu_notifier); |
2058 | 2065 | ||