aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/fcoe/fcoe.c31
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 */
1961int fcoe_hostlist_add(const struct fc_lport *lport) 1959int 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