diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 202 |
1 files changed, 64 insertions, 138 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index bde6ee5333eb..5d3700dc6f8c 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -381,6 +381,42 @@ out: | |||
381 | } | 381 | } |
382 | 382 | ||
383 | /** | 383 | /** |
384 | * fcoe_interface_release() - fcoe_port kref release function | ||
385 | * @kref: Embedded reference count in an fcoe_interface struct | ||
386 | */ | ||
387 | static void fcoe_interface_release(struct kref *kref) | ||
388 | { | ||
389 | struct fcoe_interface *fcoe; | ||
390 | struct net_device *netdev; | ||
391 | |||
392 | fcoe = container_of(kref, struct fcoe_interface, kref); | ||
393 | netdev = fcoe->netdev; | ||
394 | /* tear-down the FCoE controller */ | ||
395 | fcoe_ctlr_destroy(&fcoe->ctlr); | ||
396 | kfree(fcoe); | ||
397 | dev_put(netdev); | ||
398 | module_put(THIS_MODULE); | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * fcoe_interface_get() - Get a reference to a FCoE interface | ||
403 | * @fcoe: The FCoE interface to be held | ||
404 | */ | ||
405 | static inline void fcoe_interface_get(struct fcoe_interface *fcoe) | ||
406 | { | ||
407 | kref_get(&fcoe->kref); | ||
408 | } | ||
409 | |||
410 | /** | ||
411 | * fcoe_interface_put() - Put a reference to a FCoE interface | ||
412 | * @fcoe: The FCoE interface to be released | ||
413 | */ | ||
414 | static inline void fcoe_interface_put(struct fcoe_interface *fcoe) | ||
415 | { | ||
416 | kref_put(&fcoe->kref, fcoe_interface_release); | ||
417 | } | ||
418 | |||
419 | /** | ||
384 | * fcoe_interface_cleanup() - Clean up a FCoE interface | 420 | * fcoe_interface_cleanup() - Clean up a FCoE interface |
385 | * @fcoe: The FCoE interface to be cleaned up | 421 | * @fcoe: The FCoE interface to be cleaned up |
386 | * | 422 | * |
@@ -392,6 +428,21 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
392 | struct fcoe_ctlr *fip = &fcoe->ctlr; | 428 | struct fcoe_ctlr *fip = &fcoe->ctlr; |
393 | u8 flogi_maddr[ETH_ALEN]; | 429 | u8 flogi_maddr[ETH_ALEN]; |
394 | const struct net_device_ops *ops; | 430 | const struct net_device_ops *ops; |
431 | struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); | ||
432 | |||
433 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); | ||
434 | |||
435 | /* Logout of the fabric */ | ||
436 | fc_fabric_logoff(fcoe->ctlr.lp); | ||
437 | |||
438 | /* Cleanup the fc_lport */ | ||
439 | fc_lport_destroy(fcoe->ctlr.lp); | ||
440 | |||
441 | /* Stop the transmit retry timer */ | ||
442 | del_timer_sync(&port->timer); | ||
443 | |||
444 | /* Free existing transmit skbs */ | ||
445 | fcoe_clean_pending_queue(fcoe->ctlr.lp); | ||
395 | 446 | ||
396 | /* | 447 | /* |
397 | * Don't listen for Ethernet packets anymore. | 448 | * Don't listen for Ethernet packets anymore. |
@@ -414,6 +465,9 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
414 | } else | 465 | } else |
415 | dev_mc_del(netdev, FIP_ALL_ENODE_MACS); | 466 | dev_mc_del(netdev, FIP_ALL_ENODE_MACS); |
416 | 467 | ||
468 | if (!is_zero_ether_addr(port->data_src_addr)) | ||
469 | dev_uc_del(netdev, port->data_src_addr); | ||
470 | |||
417 | /* Tell the LLD we are done w/ FCoE */ | 471 | /* Tell the LLD we are done w/ FCoE */ |
418 | ops = netdev->netdev_ops; | 472 | ops = netdev->netdev_ops; |
419 | if (ops->ndo_fcoe_disable) { | 473 | if (ops->ndo_fcoe_disable) { |
@@ -421,42 +475,7 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
421 | FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" | 475 | FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" |
422 | " specific feature for LLD.\n"); | 476 | " specific feature for LLD.\n"); |
423 | } | 477 | } |
424 | } | 478 | fcoe_interface_put(fcoe); |
425 | |||
426 | /** | ||
427 | * fcoe_interface_release() - fcoe_port kref release function | ||
428 | * @kref: Embedded reference count in an fcoe_interface struct | ||
429 | */ | ||
430 | static void fcoe_interface_release(struct kref *kref) | ||
431 | { | ||
432 | struct fcoe_interface *fcoe; | ||
433 | struct net_device *netdev; | ||
434 | |||
435 | fcoe = container_of(kref, struct fcoe_interface, kref); | ||
436 | netdev = fcoe->netdev; | ||
437 | /* tear-down the FCoE controller */ | ||
438 | fcoe_ctlr_destroy(&fcoe->ctlr); | ||
439 | kfree(fcoe); | ||
440 | dev_put(netdev); | ||
441 | module_put(THIS_MODULE); | ||
442 | } | ||
443 | |||
444 | /** | ||
445 | * fcoe_interface_get() - Get a reference to a FCoE interface | ||
446 | * @fcoe: The FCoE interface to be held | ||
447 | */ | ||
448 | static inline void fcoe_interface_get(struct fcoe_interface *fcoe) | ||
449 | { | ||
450 | kref_get(&fcoe->kref); | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * fcoe_interface_put() - Put a reference to a FCoE interface | ||
455 | * @fcoe: The FCoE interface to be released | ||
456 | */ | ||
457 | static inline void fcoe_interface_put(struct fcoe_interface *fcoe) | ||
458 | { | ||
459 | kref_put(&fcoe->kref, fcoe_interface_release); | ||
460 | } | 479 | } |
461 | 480 | ||
462 | /** | 481 | /** |
@@ -821,39 +840,9 @@ skip_oem: | |||
821 | * fcoe_if_destroy() - Tear down a SW FCoE instance | 840 | * fcoe_if_destroy() - Tear down a SW FCoE instance |
822 | * @lport: The local port to be destroyed | 841 | * @lport: The local port to be destroyed |
823 | * | 842 | * |
824 | * Locking: must be called with the RTNL mutex held and RTNL mutex | ||
825 | * needed to be dropped by this function since not dropping RTNL | ||
826 | * would cause circular locking warning on synchronous fip worker | ||
827 | * cancelling thru fcoe_interface_put invoked by this function. | ||
828 | * | ||
829 | */ | 843 | */ |
830 | static void fcoe_if_destroy(struct fc_lport *lport) | 844 | static void fcoe_if_destroy(struct fc_lport *lport) |
831 | { | 845 | { |
832 | struct fcoe_port *port = lport_priv(lport); | ||
833 | struct fcoe_interface *fcoe = port->priv; | ||
834 | struct net_device *netdev = fcoe->netdev; | ||
835 | |||
836 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); | ||
837 | |||
838 | /* Logout of the fabric */ | ||
839 | fc_fabric_logoff(lport); | ||
840 | |||
841 | /* Cleanup the fc_lport */ | ||
842 | fc_lport_destroy(lport); | ||
843 | |||
844 | /* Stop the transmit retry timer */ | ||
845 | del_timer_sync(&port->timer); | ||
846 | |||
847 | /* Free existing transmit skbs */ | ||
848 | fcoe_clean_pending_queue(lport); | ||
849 | |||
850 | if (!is_zero_ether_addr(port->data_src_addr)) | ||
851 | dev_uc_del(netdev, port->data_src_addr); | ||
852 | rtnl_unlock(); | ||
853 | |||
854 | /* receives may not be stopped until after this */ | ||
855 | fcoe_interface_put(fcoe); | ||
856 | |||
857 | /* Free queued packets for the per-CPU receive threads */ | 846 | /* Free queued packets for the per-CPU receive threads */ |
858 | fcoe_percpu_clean(lport); | 847 | fcoe_percpu_clean(lport); |
859 | 848 | ||
@@ -1783,23 +1772,8 @@ static int fcoe_disable(struct net_device *netdev) | |||
1783 | int rc = 0; | 1772 | int rc = 0; |
1784 | 1773 | ||
1785 | mutex_lock(&fcoe_config_mutex); | 1774 | mutex_lock(&fcoe_config_mutex); |
1786 | #ifdef CONFIG_FCOE_MODULE | ||
1787 | /* | ||
1788 | * Make sure the module has been initialized, and is not about to be | ||
1789 | * removed. Module paramter sysfs files are writable before the | ||
1790 | * module_init function is called and after module_exit. | ||
1791 | */ | ||
1792 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1793 | rc = -ENODEV; | ||
1794 | goto out_nodev; | ||
1795 | } | ||
1796 | #endif | ||
1797 | |||
1798 | if (!rtnl_trylock()) { | ||
1799 | mutex_unlock(&fcoe_config_mutex); | ||
1800 | return -ERESTARTSYS; | ||
1801 | } | ||
1802 | 1775 | ||
1776 | rtnl_lock(); | ||
1803 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1777 | fcoe = fcoe_hostlist_lookup_port(netdev); |
1804 | rtnl_unlock(); | 1778 | rtnl_unlock(); |
1805 | 1779 | ||
@@ -1809,7 +1783,6 @@ static int fcoe_disable(struct net_device *netdev) | |||
1809 | } else | 1783 | } else |
1810 | rc = -ENODEV; | 1784 | rc = -ENODEV; |
1811 | 1785 | ||
1812 | out_nodev: | ||
1813 | mutex_unlock(&fcoe_config_mutex); | 1786 | mutex_unlock(&fcoe_config_mutex); |
1814 | return rc; | 1787 | return rc; |
1815 | } | 1788 | } |
@@ -1828,22 +1801,7 @@ static int fcoe_enable(struct net_device *netdev) | |||
1828 | int rc = 0; | 1801 | int rc = 0; |
1829 | 1802 | ||
1830 | mutex_lock(&fcoe_config_mutex); | 1803 | mutex_lock(&fcoe_config_mutex); |
1831 | #ifdef CONFIG_FCOE_MODULE | 1804 | rtnl_lock(); |
1832 | /* | ||
1833 | * Make sure the module has been initialized, and is not about to be | ||
1834 | * removed. Module paramter sysfs files are writable before the | ||
1835 | * module_init function is called and after module_exit. | ||
1836 | */ | ||
1837 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1838 | rc = -ENODEV; | ||
1839 | goto out_nodev; | ||
1840 | } | ||
1841 | #endif | ||
1842 | if (!rtnl_trylock()) { | ||
1843 | mutex_unlock(&fcoe_config_mutex); | ||
1844 | return -ERESTARTSYS; | ||
1845 | } | ||
1846 | |||
1847 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1805 | fcoe = fcoe_hostlist_lookup_port(netdev); |
1848 | rtnl_unlock(); | 1806 | rtnl_unlock(); |
1849 | 1807 | ||
@@ -1852,7 +1810,6 @@ static int fcoe_enable(struct net_device *netdev) | |||
1852 | else if (!fcoe_link_ok(fcoe->ctlr.lp)) | 1810 | else if (!fcoe_link_ok(fcoe->ctlr.lp)) |
1853 | fcoe_ctlr_link_up(&fcoe->ctlr); | 1811 | fcoe_ctlr_link_up(&fcoe->ctlr); |
1854 | 1812 | ||
1855 | out_nodev: | ||
1856 | mutex_unlock(&fcoe_config_mutex); | 1813 | mutex_unlock(&fcoe_config_mutex); |
1857 | return rc; | 1814 | return rc; |
1858 | } | 1815 | } |
@@ -1868,35 +1825,22 @@ out_nodev: | |||
1868 | static int fcoe_destroy(struct net_device *netdev) | 1825 | static int fcoe_destroy(struct net_device *netdev) |
1869 | { | 1826 | { |
1870 | struct fcoe_interface *fcoe; | 1827 | struct fcoe_interface *fcoe; |
1828 | struct fc_lport *lport; | ||
1871 | int rc = 0; | 1829 | int rc = 0; |
1872 | 1830 | ||
1873 | mutex_lock(&fcoe_config_mutex); | 1831 | mutex_lock(&fcoe_config_mutex); |
1874 | #ifdef CONFIG_FCOE_MODULE | 1832 | rtnl_lock(); |
1875 | /* | ||
1876 | * Make sure the module has been initialized, and is not about to be | ||
1877 | * removed. Module paramter sysfs files are writable before the | ||
1878 | * module_init function is called and after module_exit. | ||
1879 | */ | ||
1880 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1881 | rc = -ENODEV; | ||
1882 | goto out_nodev; | ||
1883 | } | ||
1884 | #endif | ||
1885 | if (!rtnl_trylock()) { | ||
1886 | mutex_unlock(&fcoe_config_mutex); | ||
1887 | return -ERESTARTSYS; | ||
1888 | } | ||
1889 | |||
1890 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1833 | fcoe = fcoe_hostlist_lookup_port(netdev); |
1891 | if (!fcoe) { | 1834 | if (!fcoe) { |
1892 | rtnl_unlock(); | 1835 | rtnl_unlock(); |
1893 | rc = -ENODEV; | 1836 | rc = -ENODEV; |
1894 | goto out_nodev; | 1837 | goto out_nodev; |
1895 | } | 1838 | } |
1896 | fcoe_interface_cleanup(fcoe); | 1839 | lport = fcoe->ctlr.lp; |
1897 | list_del(&fcoe->list); | 1840 | list_del(&fcoe->list); |
1898 | /* RTNL mutex is dropped by fcoe_if_destroy */ | 1841 | fcoe_interface_cleanup(fcoe); |
1899 | fcoe_if_destroy(fcoe->ctlr.lp); | 1842 | rtnl_unlock(); |
1843 | fcoe_if_destroy(lport); | ||
1900 | out_nodev: | 1844 | out_nodev: |
1901 | mutex_unlock(&fcoe_config_mutex); | 1845 | mutex_unlock(&fcoe_config_mutex); |
1902 | return rc; | 1846 | return rc; |
@@ -1912,8 +1856,6 @@ static void fcoe_destroy_work(struct work_struct *work) | |||
1912 | 1856 | ||
1913 | port = container_of(work, struct fcoe_port, destroy_work); | 1857 | port = container_of(work, struct fcoe_port, destroy_work); |
1914 | mutex_lock(&fcoe_config_mutex); | 1858 | mutex_lock(&fcoe_config_mutex); |
1915 | rtnl_lock(); | ||
1916 | /* RTNL mutex is dropped by fcoe_if_destroy */ | ||
1917 | fcoe_if_destroy(port->lport); | 1859 | fcoe_if_destroy(port->lport); |
1918 | mutex_unlock(&fcoe_config_mutex); | 1860 | mutex_unlock(&fcoe_config_mutex); |
1919 | } | 1861 | } |
@@ -1948,23 +1890,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
1948 | struct fc_lport *lport; | 1890 | struct fc_lport *lport; |
1949 | 1891 | ||
1950 | mutex_lock(&fcoe_config_mutex); | 1892 | mutex_lock(&fcoe_config_mutex); |
1951 | 1893 | rtnl_lock(); | |
1952 | if (!rtnl_trylock()) { | ||
1953 | mutex_unlock(&fcoe_config_mutex); | ||
1954 | return -ERESTARTSYS; | ||
1955 | } | ||
1956 | |||
1957 | #ifdef CONFIG_FCOE_MODULE | ||
1958 | /* | ||
1959 | * Make sure the module has been initialized, and is not about to be | ||
1960 | * removed. Module paramter sysfs files are writable before the | ||
1961 | * module_init function is called and after module_exit. | ||
1962 | */ | ||
1963 | if (THIS_MODULE->state != MODULE_STATE_LIVE) { | ||
1964 | rc = -ENODEV; | ||
1965 | goto out_nodev; | ||
1966 | } | ||
1967 | #endif | ||
1968 | 1894 | ||
1969 | /* look for existing lport */ | 1895 | /* look for existing lport */ |
1970 | if (fcoe_hostlist_lookup(netdev)) { | 1896 | if (fcoe_hostlist_lookup(netdev)) { |