diff options
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 170 |
1 files changed, 62 insertions, 108 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 6d6c8bf5d155..8a1005d117b7 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -101,10 +101,11 @@ static int fcoe_ddp_done(struct fc_lport *, u16); | |||
101 | 101 | ||
102 | static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); | 102 | static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); |
103 | 103 | ||
104 | static int fcoe_create(const char *, struct kernel_param *); | 104 | static bool fcoe_match(struct net_device *netdev); |
105 | static int fcoe_destroy(const char *, struct kernel_param *); | 105 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode); |
106 | static int fcoe_enable(const char *, struct kernel_param *); | 106 | static int fcoe_destroy(struct net_device *netdev); |
107 | static int fcoe_disable(const char *, struct kernel_param *); | 107 | static int fcoe_enable(struct net_device *netdev); |
108 | static int fcoe_disable(struct net_device *netdev); | ||
108 | 109 | ||
109 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, | 110 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, |
110 | u32 did, struct fc_frame *, | 111 | u32 did, struct fc_frame *, |
@@ -117,24 +118,6 @@ static void fcoe_recv_frame(struct sk_buff *skb); | |||
117 | 118 | ||
118 | static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); | 119 | static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *); |
119 | 120 | ||
120 | module_param_call(create, fcoe_create, NULL, (void *)FIP_MODE_FABRIC, S_IWUSR); | ||
121 | __MODULE_PARM_TYPE(create, "string"); | ||
122 | MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface"); | ||
123 | module_param_call(create_vn2vn, fcoe_create, NULL, | ||
124 | (void *)FIP_MODE_VN2VN, S_IWUSR); | ||
125 | __MODULE_PARM_TYPE(create_vn2vn, "string"); | ||
126 | MODULE_PARM_DESC(create_vn2vn, " Creates a VN_node to VN_node FCoE instance " | ||
127 | "on an Ethernet interface"); | ||
128 | module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); | ||
129 | __MODULE_PARM_TYPE(destroy, "string"); | ||
130 | MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface"); | ||
131 | module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR); | ||
132 | __MODULE_PARM_TYPE(enable, "string"); | ||
133 | MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface."); | ||
134 | module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR); | ||
135 | __MODULE_PARM_TYPE(disable, "string"); | ||
136 | MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface."); | ||
137 | |||
138 | /* notification function for packets from net device */ | 121 | /* notification function for packets from net device */ |
139 | static struct notifier_block fcoe_notifier = { | 122 | static struct notifier_block fcoe_notifier = { |
140 | .notifier_call = fcoe_device_notification, | 123 | .notifier_call = fcoe_device_notification, |
@@ -1939,39 +1922,16 @@ out: | |||
1939 | } | 1922 | } |
1940 | 1923 | ||
1941 | /** | 1924 | /** |
1942 | * fcoe_if_to_netdev() - Parse a name buffer to get a net device | ||
1943 | * @buffer: The name of the net device | ||
1944 | * | ||
1945 | * Returns: NULL or a ptr to net_device | ||
1946 | */ | ||
1947 | static struct net_device *fcoe_if_to_netdev(const char *buffer) | ||
1948 | { | ||
1949 | char *cp; | ||
1950 | char ifname[IFNAMSIZ + 2]; | ||
1951 | |||
1952 | if (buffer) { | ||
1953 | strlcpy(ifname, buffer, IFNAMSIZ); | ||
1954 | cp = ifname + strlen(ifname); | ||
1955 | while (--cp >= ifname && *cp == '\n') | ||
1956 | *cp = '\0'; | ||
1957 | return dev_get_by_name(&init_net, ifname); | ||
1958 | } | ||
1959 | return NULL; | ||
1960 | } | ||
1961 | |||
1962 | /** | ||
1963 | * fcoe_disable() - Disables a FCoE interface | 1925 | * fcoe_disable() - Disables a FCoE interface |
1964 | * @buffer: The name of the Ethernet interface to be disabled | 1926 | * @netdev : The net_device object the Ethernet interface to create on |
1965 | * @kp: The associated kernel parameter | ||
1966 | * | 1927 | * |
1967 | * Called from sysfs. | 1928 | * Called from fcoe transport. |
1968 | * | 1929 | * |
1969 | * Returns: 0 for success | 1930 | * Returns: 0 for success |
1970 | */ | 1931 | */ |
1971 | static int fcoe_disable(const char *buffer, struct kernel_param *kp) | 1932 | static int fcoe_disable(struct net_device *netdev) |
1972 | { | 1933 | { |
1973 | struct fcoe_interface *fcoe; | 1934 | struct fcoe_interface *fcoe; |
1974 | struct net_device *netdev; | ||
1975 | int rc = 0; | 1935 | int rc = 0; |
1976 | 1936 | ||
1977 | mutex_lock(&fcoe_config_mutex); | 1937 | mutex_lock(&fcoe_config_mutex); |
@@ -1987,16 +1947,9 @@ static int fcoe_disable(const char *buffer, struct kernel_param *kp) | |||
1987 | } | 1947 | } |
1988 | #endif | 1948 | #endif |
1989 | 1949 | ||
1990 | netdev = fcoe_if_to_netdev(buffer); | ||
1991 | if (!netdev) { | ||
1992 | rc = -ENODEV; | ||
1993 | goto out_nodev; | ||
1994 | } | ||
1995 | |||
1996 | if (!rtnl_trylock()) { | 1950 | if (!rtnl_trylock()) { |
1997 | dev_put(netdev); | ||
1998 | mutex_unlock(&fcoe_config_mutex); | 1951 | mutex_unlock(&fcoe_config_mutex); |
1999 | return restart_syscall(); | 1952 | return -ERESTARTSYS; |
2000 | } | 1953 | } |
2001 | 1954 | ||
2002 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1955 | fcoe = fcoe_hostlist_lookup_port(netdev); |
@@ -2008,7 +1961,6 @@ static int fcoe_disable(const char *buffer, struct kernel_param *kp) | |||
2008 | } else | 1961 | } else |
2009 | rc = -ENODEV; | 1962 | rc = -ENODEV; |
2010 | 1963 | ||
2011 | dev_put(netdev); | ||
2012 | out_nodev: | 1964 | out_nodev: |
2013 | mutex_unlock(&fcoe_config_mutex); | 1965 | mutex_unlock(&fcoe_config_mutex); |
2014 | return rc; | 1966 | return rc; |
@@ -2016,17 +1968,15 @@ out_nodev: | |||
2016 | 1968 | ||
2017 | /** | 1969 | /** |
2018 | * fcoe_enable() - Enables a FCoE interface | 1970 | * fcoe_enable() - Enables a FCoE interface |
2019 | * @buffer: The name of the Ethernet interface to be enabled | 1971 | * @netdev : The net_device object the Ethernet interface to create on |
2020 | * @kp: The associated kernel parameter | ||
2021 | * | 1972 | * |
2022 | * Called from sysfs. | 1973 | * Called from fcoe transport. |
2023 | * | 1974 | * |
2024 | * Returns: 0 for success | 1975 | * Returns: 0 for success |
2025 | */ | 1976 | */ |
2026 | static int fcoe_enable(const char *buffer, struct kernel_param *kp) | 1977 | static int fcoe_enable(struct net_device *netdev) |
2027 | { | 1978 | { |
2028 | struct fcoe_interface *fcoe; | 1979 | struct fcoe_interface *fcoe; |
2029 | struct net_device *netdev; | ||
2030 | int rc = 0; | 1980 | int rc = 0; |
2031 | 1981 | ||
2032 | mutex_lock(&fcoe_config_mutex); | 1982 | mutex_lock(&fcoe_config_mutex); |
@@ -2041,17 +1991,9 @@ static int fcoe_enable(const char *buffer, struct kernel_param *kp) | |||
2041 | goto out_nodev; | 1991 | goto out_nodev; |
2042 | } | 1992 | } |
2043 | #endif | 1993 | #endif |
2044 | |||
2045 | netdev = fcoe_if_to_netdev(buffer); | ||
2046 | if (!netdev) { | ||
2047 | rc = -ENODEV; | ||
2048 | goto out_nodev; | ||
2049 | } | ||
2050 | |||
2051 | if (!rtnl_trylock()) { | 1994 | if (!rtnl_trylock()) { |
2052 | dev_put(netdev); | ||
2053 | mutex_unlock(&fcoe_config_mutex); | 1995 | mutex_unlock(&fcoe_config_mutex); |
2054 | return restart_syscall(); | 1996 | return -ERESTARTSYS; |
2055 | } | 1997 | } |
2056 | 1998 | ||
2057 | fcoe = fcoe_hostlist_lookup_port(netdev); | 1999 | fcoe = fcoe_hostlist_lookup_port(netdev); |
@@ -2062,7 +2004,6 @@ static int fcoe_enable(const char *buffer, struct kernel_param *kp) | |||
2062 | else if (!fcoe_link_ok(fcoe->ctlr.lp)) | 2004 | else if (!fcoe_link_ok(fcoe->ctlr.lp)) |
2063 | fcoe_ctlr_link_up(&fcoe->ctlr); | 2005 | fcoe_ctlr_link_up(&fcoe->ctlr); |
2064 | 2006 | ||
2065 | dev_put(netdev); | ||
2066 | out_nodev: | 2007 | out_nodev: |
2067 | mutex_unlock(&fcoe_config_mutex); | 2008 | mutex_unlock(&fcoe_config_mutex); |
2068 | return rc; | 2009 | return rc; |
@@ -2070,17 +2011,15 @@ out_nodev: | |||
2070 | 2011 | ||
2071 | /** | 2012 | /** |
2072 | * fcoe_destroy() - Destroy a FCoE interface | 2013 | * fcoe_destroy() - Destroy a FCoE interface |
2073 | * @buffer: The name of the Ethernet interface to be destroyed | 2014 | * @netdev : The net_device object the Ethernet interface to create on |
2074 | * @kp: The associated kernel parameter | ||
2075 | * | 2015 | * |
2076 | * Called from sysfs. | 2016 | * Called from fcoe transport |
2077 | * | 2017 | * |
2078 | * Returns: 0 for success | 2018 | * Returns: 0 for success |
2079 | */ | 2019 | */ |
2080 | static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | 2020 | static int fcoe_destroy(struct net_device *netdev) |
2081 | { | 2021 | { |
2082 | struct fcoe_interface *fcoe; | 2022 | struct fcoe_interface *fcoe; |
2083 | struct net_device *netdev; | ||
2084 | int rc = 0; | 2023 | int rc = 0; |
2085 | 2024 | ||
2086 | mutex_lock(&fcoe_config_mutex); | 2025 | mutex_lock(&fcoe_config_mutex); |
@@ -2095,32 +2034,21 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
2095 | goto out_nodev; | 2034 | goto out_nodev; |
2096 | } | 2035 | } |
2097 | #endif | 2036 | #endif |
2098 | |||
2099 | netdev = fcoe_if_to_netdev(buffer); | ||
2100 | if (!netdev) { | ||
2101 | rc = -ENODEV; | ||
2102 | goto out_nodev; | ||
2103 | } | ||
2104 | |||
2105 | if (!rtnl_trylock()) { | 2037 | if (!rtnl_trylock()) { |
2106 | dev_put(netdev); | ||
2107 | mutex_unlock(&fcoe_config_mutex); | 2038 | mutex_unlock(&fcoe_config_mutex); |
2108 | return restart_syscall(); | 2039 | return -ERESTARTSYS; |
2109 | } | 2040 | } |
2110 | 2041 | ||
2111 | fcoe = fcoe_hostlist_lookup_port(netdev); | 2042 | fcoe = fcoe_hostlist_lookup_port(netdev); |
2112 | if (!fcoe) { | 2043 | if (!fcoe) { |
2113 | rtnl_unlock(); | 2044 | rtnl_unlock(); |
2114 | rc = -ENODEV; | 2045 | rc = -ENODEV; |
2115 | goto out_putdev; | 2046 | goto out_nodev; |
2116 | } | 2047 | } |
2117 | fcoe_interface_cleanup(fcoe); | 2048 | fcoe_interface_cleanup(fcoe); |
2118 | list_del(&fcoe->list); | 2049 | list_del(&fcoe->list); |
2119 | /* RTNL mutex is dropped by fcoe_if_destroy */ | 2050 | /* RTNL mutex is dropped by fcoe_if_destroy */ |
2120 | fcoe_if_destroy(fcoe->ctlr.lp); | 2051 | fcoe_if_destroy(fcoe->ctlr.lp); |
2121 | |||
2122 | out_putdev: | ||
2123 | dev_put(netdev); | ||
2124 | out_nodev: | 2052 | out_nodev: |
2125 | mutex_unlock(&fcoe_config_mutex); | 2053 | mutex_unlock(&fcoe_config_mutex); |
2126 | return rc; | 2054 | return rc; |
@@ -2143,27 +2071,39 @@ static void fcoe_destroy_work(struct work_struct *work) | |||
2143 | } | 2071 | } |
2144 | 2072 | ||
2145 | /** | 2073 | /** |
2074 | * fcoe_match() - Check if the FCoE is supported on the given netdevice | ||
2075 | * @netdev : The net_device object the Ethernet interface to create on | ||
2076 | * | ||
2077 | * Called from fcoe transport. | ||
2078 | * | ||
2079 | * Returns: always returns true as this is the default FCoE transport, | ||
2080 | * i.e., support all netdevs. | ||
2081 | */ | ||
2082 | static bool fcoe_match(struct net_device *netdev) | ||
2083 | { | ||
2084 | return true; | ||
2085 | } | ||
2086 | |||
2087 | /** | ||
2146 | * fcoe_create() - Create a fcoe interface | 2088 | * fcoe_create() - Create a fcoe interface |
2147 | * @buffer: The name of the Ethernet interface to create on | 2089 | * @netdev : The net_device object the Ethernet interface to create on |
2148 | * @kp: The associated kernel param | 2090 | * @fip_mode: The FIP mode for this creation |
2149 | * | 2091 | * |
2150 | * Called from sysfs. | 2092 | * Called from fcoe transport |
2151 | * | 2093 | * |
2152 | * Returns: 0 for success | 2094 | * Returns: 0 for success |
2153 | */ | 2095 | */ |
2154 | static int fcoe_create(const char *buffer, struct kernel_param *kp) | 2096 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) |
2155 | { | 2097 | { |
2156 | enum fip_state fip_mode = (enum fip_state)(long)kp->arg; | ||
2157 | int rc; | 2098 | int rc; |
2158 | struct fcoe_interface *fcoe; | 2099 | struct fcoe_interface *fcoe; |
2159 | struct fc_lport *lport; | 2100 | struct fc_lport *lport; |
2160 | struct net_device *netdev; | ||
2161 | 2101 | ||
2162 | mutex_lock(&fcoe_config_mutex); | 2102 | mutex_lock(&fcoe_config_mutex); |
2163 | 2103 | ||
2164 | if (!rtnl_trylock()) { | 2104 | if (!rtnl_trylock()) { |
2165 | mutex_unlock(&fcoe_config_mutex); | 2105 | mutex_unlock(&fcoe_config_mutex); |
2166 | return restart_syscall(); | 2106 | return -ERESTARTSYS; |
2167 | } | 2107 | } |
2168 | 2108 | ||
2169 | #ifdef CONFIG_FCOE_MODULE | 2109 | #ifdef CONFIG_FCOE_MODULE |
@@ -2178,22 +2118,16 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2178 | } | 2118 | } |
2179 | #endif | 2119 | #endif |
2180 | 2120 | ||
2181 | netdev = fcoe_if_to_netdev(buffer); | ||
2182 | if (!netdev) { | ||
2183 | rc = -ENODEV; | ||
2184 | goto out_nodev; | ||
2185 | } | ||
2186 | |||
2187 | /* look for existing lport */ | 2121 | /* look for existing lport */ |
2188 | if (fcoe_hostlist_lookup(netdev)) { | 2122 | if (fcoe_hostlist_lookup(netdev)) { |
2189 | rc = -EEXIST; | 2123 | rc = -EEXIST; |
2190 | goto out_putdev; | 2124 | goto out_nodev; |
2191 | } | 2125 | } |
2192 | 2126 | ||
2193 | fcoe = fcoe_interface_create(netdev, fip_mode); | 2127 | fcoe = fcoe_interface_create(netdev, fip_mode); |
2194 | if (IS_ERR(fcoe)) { | 2128 | if (IS_ERR(fcoe)) { |
2195 | rc = PTR_ERR(fcoe); | 2129 | rc = PTR_ERR(fcoe); |
2196 | goto out_putdev; | 2130 | goto out_nodev; |
2197 | } | 2131 | } |
2198 | 2132 | ||
2199 | lport = fcoe_if_create(fcoe, &netdev->dev, 0); | 2133 | lport = fcoe_if_create(fcoe, &netdev->dev, 0); |
@@ -2222,15 +2156,12 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2222 | * should be holding a reference taken in fcoe_if_create(). | 2156 | * should be holding a reference taken in fcoe_if_create(). |
2223 | */ | 2157 | */ |
2224 | fcoe_interface_put(fcoe); | 2158 | fcoe_interface_put(fcoe); |
2225 | dev_put(netdev); | ||
2226 | rtnl_unlock(); | 2159 | rtnl_unlock(); |
2227 | mutex_unlock(&fcoe_config_mutex); | 2160 | mutex_unlock(&fcoe_config_mutex); |
2228 | 2161 | ||
2229 | return 0; | 2162 | return 0; |
2230 | out_free: | 2163 | out_free: |
2231 | fcoe_interface_put(fcoe); | 2164 | fcoe_interface_put(fcoe); |
2232 | out_putdev: | ||
2233 | dev_put(netdev); | ||
2234 | out_nodev: | 2165 | out_nodev: |
2235 | rtnl_unlock(); | 2166 | rtnl_unlock(); |
2236 | mutex_unlock(&fcoe_config_mutex); | 2167 | mutex_unlock(&fcoe_config_mutex); |
@@ -2433,6 +2364,18 @@ static int fcoe_hostlist_add(const struct fc_lport *lport) | |||
2433 | return 0; | 2364 | return 0; |
2434 | } | 2365 | } |
2435 | 2366 | ||
2367 | |||
2368 | static struct fcoe_transport fcoe_sw_transport = { | ||
2369 | .name = {FCOE_TRANSPORT_DEFAULT}, | ||
2370 | .attached = false, | ||
2371 | .list = LIST_HEAD_INIT(fcoe_sw_transport.list), | ||
2372 | .match = fcoe_match, | ||
2373 | .create = fcoe_create, | ||
2374 | .destroy = fcoe_destroy, | ||
2375 | .enable = fcoe_enable, | ||
2376 | .disable = fcoe_disable, | ||
2377 | }; | ||
2378 | |||
2436 | /** | 2379 | /** |
2437 | * fcoe_init() - Initialize fcoe.ko | 2380 | * fcoe_init() - Initialize fcoe.ko |
2438 | * | 2381 | * |
@@ -2444,6 +2387,14 @@ static int __init fcoe_init(void) | |||
2444 | unsigned int cpu; | 2387 | unsigned int cpu; |
2445 | int rc = 0; | 2388 | int rc = 0; |
2446 | 2389 | ||
2390 | /* register as a fcoe transport */ | ||
2391 | rc = fcoe_transport_attach(&fcoe_sw_transport); | ||
2392 | if (rc) { | ||
2393 | printk(KERN_ERR "failed to register an fcoe transport, check " | ||
2394 | "if libfcoe is loaded\n"); | ||
2395 | return rc; | ||
2396 | } | ||
2397 | |||
2447 | mutex_lock(&fcoe_config_mutex); | 2398 | mutex_lock(&fcoe_config_mutex); |
2448 | 2399 | ||
2449 | for_each_possible_cpu(cpu) { | 2400 | for_each_possible_cpu(cpu) { |
@@ -2520,6 +2471,9 @@ static void __exit fcoe_exit(void) | |||
2520 | /* detach from scsi transport | 2471 | /* detach from scsi transport |
2521 | * must happen after all destroys are done, therefor after the flush */ | 2472 | * must happen after all destroys are done, therefor after the flush */ |
2522 | fcoe_if_exit(); | 2473 | fcoe_if_exit(); |
2474 | |||
2475 | /* detach from fcoe transport */ | ||
2476 | fcoe_transport_detach(&fcoe_sw_transport); | ||
2523 | } | 2477 | } |
2524 | module_exit(fcoe_exit); | 2478 | module_exit(fcoe_exit); |
2525 | 2479 | ||