diff options
author | Robert Love <robert.w.love@intel.com> | 2012-11-27 01:53:35 -0500 |
---|---|---|
committer | Robert Love <robert.w.love@intel.com> | 2012-12-14 13:38:54 -0500 |
commit | 435c86679a24ead623c8a47ca31038e250a75e05 (patch) | |
tree | 2ee9bc3a2d338bc641c099f9c7aa792bf1db0460 /drivers/scsi | |
parent | 6a891b071b640e1de44c4a5117fa2c974dcfa84a (diff) |
fcoe: Use the fcoe_sysfs control interface
This patch adds support for the new fcoe_sysfs
control interface to fcoe.ko. It keeps the deprecated
interface in tact and therefore either the legacy
or the new control interfaces can be used. A mixed mode
is not supported. A user must either use the new
interfaces or the old ones, but not both.
The fcoe_ctlr's link state is now driven by both the
netdev link state as well as the fcoe_ctlr_device's
enabled attribute. The link must be up and the
fcoe_ctlr_device must be enabled before the FCoE
Controller starts discovery or login.
Signed-off-by: Robert Love <robert.w.love@intel.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 147 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe_ctlr.c | 17 |
2 files changed, 140 insertions, 24 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 9bd982d2c07f..21927f7952d8 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -117,6 +117,11 @@ static int fcoe_destroy(struct net_device *netdev); | |||
117 | static int fcoe_enable(struct net_device *netdev); | 117 | static int fcoe_enable(struct net_device *netdev); |
118 | static int fcoe_disable(struct net_device *netdev); | 118 | static int fcoe_disable(struct net_device *netdev); |
119 | 119 | ||
120 | /* fcoe_syfs control interface handlers */ | ||
121 | static int fcoe_ctlr_alloc(struct net_device *netdev); | ||
122 | static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev); | ||
123 | |||
124 | |||
120 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, | 125 | static struct fc_seq *fcoe_elsct_send(struct fc_lport *, |
121 | u32 did, struct fc_frame *, | 126 | u32 did, struct fc_frame *, |
122 | unsigned int op, | 127 | unsigned int op, |
@@ -155,6 +160,8 @@ static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *); | |||
155 | static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); | 160 | static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); |
156 | 161 | ||
157 | static struct fcoe_sysfs_function_template fcoe_sysfs_templ = { | 162 | static struct fcoe_sysfs_function_template fcoe_sysfs_templ = { |
163 | .set_fcoe_ctlr_mode = fcoe_ctlr_set_fip_mode, | ||
164 | .set_fcoe_ctlr_enabled = fcoe_ctlr_enabled, | ||
158 | .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb, | 165 | .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb, |
159 | .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb, | 166 | .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb, |
160 | .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb, | 167 | .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb, |
@@ -1963,6 +1970,7 @@ static int fcoe_dcb_app_notification(struct notifier_block *notifier, | |||
1963 | static int fcoe_device_notification(struct notifier_block *notifier, | 1970 | static int fcoe_device_notification(struct notifier_block *notifier, |
1964 | ulong event, void *ptr) | 1971 | ulong event, void *ptr) |
1965 | { | 1972 | { |
1973 | struct fcoe_ctlr_device *cdev; | ||
1966 | struct fc_lport *lport = NULL; | 1974 | struct fc_lport *lport = NULL; |
1967 | struct net_device *netdev = ptr; | 1975 | struct net_device *netdev = ptr; |
1968 | struct fcoe_ctlr *ctlr; | 1976 | struct fcoe_ctlr *ctlr; |
@@ -2019,13 +2027,29 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
2019 | 2027 | ||
2020 | fcoe_link_speed_update(lport); | 2028 | fcoe_link_speed_update(lport); |
2021 | 2029 | ||
2022 | if (link_possible && !fcoe_link_ok(lport)) | 2030 | cdev = fcoe_ctlr_to_ctlr_dev(ctlr); |
2023 | fcoe_ctlr_link_up(ctlr); | 2031 | |
2024 | else if (fcoe_ctlr_link_down(ctlr)) { | 2032 | if (link_possible && !fcoe_link_ok(lport)) { |
2025 | stats = per_cpu_ptr(lport->stats, get_cpu()); | 2033 | switch (cdev->enabled) { |
2026 | stats->LinkFailureCount++; | 2034 | case FCOE_CTLR_DISABLED: |
2027 | put_cpu(); | 2035 | pr_info("Link up while interface is disabled.\n"); |
2028 | fcoe_clean_pending_queue(lport); | 2036 | break; |
2037 | case FCOE_CTLR_ENABLED: | ||
2038 | case FCOE_CTLR_UNUSED: | ||
2039 | fcoe_ctlr_link_up(ctlr); | ||
2040 | }; | ||
2041 | } else if (fcoe_ctlr_link_down(ctlr)) { | ||
2042 | switch (cdev->enabled) { | ||
2043 | case FCOE_CTLR_DISABLED: | ||
2044 | pr_info("Link down while interface is disabled.\n"); | ||
2045 | break; | ||
2046 | case FCOE_CTLR_ENABLED: | ||
2047 | case FCOE_CTLR_UNUSED: | ||
2048 | stats = per_cpu_ptr(lport->stats, get_cpu()); | ||
2049 | stats->LinkFailureCount++; | ||
2050 | put_cpu(); | ||
2051 | fcoe_clean_pending_queue(lport); | ||
2052 | }; | ||
2029 | } | 2053 | } |
2030 | out: | 2054 | out: |
2031 | return rc; | 2055 | return rc; |
@@ -2038,6 +2062,8 @@ out: | |||
2038 | * Called from fcoe transport. | 2062 | * Called from fcoe transport. |
2039 | * | 2063 | * |
2040 | * Returns: 0 for success | 2064 | * Returns: 0 for success |
2065 | * | ||
2066 | * Deprecated: use fcoe_ctlr_enabled() | ||
2041 | */ | 2067 | */ |
2042 | static int fcoe_disable(struct net_device *netdev) | 2068 | static int fcoe_disable(struct net_device *netdev) |
2043 | { | 2069 | { |
@@ -2097,6 +2123,33 @@ out: | |||
2097 | } | 2123 | } |
2098 | 2124 | ||
2099 | /** | 2125 | /** |
2126 | * fcoe_ctlr_enabled() - Enable or disable an FCoE Controller | ||
2127 | * @cdev: The FCoE Controller that is being enabled or disabled | ||
2128 | * | ||
2129 | * fcoe_sysfs will ensure that the state of 'enabled' has | ||
2130 | * changed, so no checking is necessary here. This routine simply | ||
2131 | * calls fcoe_enable or fcoe_disable, both of which are deprecated. | ||
2132 | * When those routines are removed the functionality can be merged | ||
2133 | * here. | ||
2134 | */ | ||
2135 | static int fcoe_ctlr_enabled(struct fcoe_ctlr_device *cdev) | ||
2136 | { | ||
2137 | struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev); | ||
2138 | struct fc_lport *lport = ctlr->lp; | ||
2139 | struct net_device *netdev = fcoe_netdev(lport); | ||
2140 | |||
2141 | switch (cdev->enabled) { | ||
2142 | case FCOE_CTLR_ENABLED: | ||
2143 | return fcoe_enable(netdev); | ||
2144 | case FCOE_CTLR_DISABLED: | ||
2145 | return fcoe_disable(netdev); | ||
2146 | case FCOE_CTLR_UNUSED: | ||
2147 | default: | ||
2148 | return -ENOTSUPP; | ||
2149 | }; | ||
2150 | } | ||
2151 | |||
2152 | /** | ||
2100 | * fcoe_destroy() - Destroy a FCoE interface | 2153 | * fcoe_destroy() - Destroy a FCoE interface |
2101 | * @netdev : The net_device object the Ethernet interface to create on | 2154 | * @netdev : The net_device object the Ethernet interface to create on |
2102 | * | 2155 | * |
@@ -2203,16 +2256,26 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe) | |||
2203 | #endif | 2256 | #endif |
2204 | } | 2257 | } |
2205 | 2258 | ||
2259 | enum fcoe_create_link_state { | ||
2260 | FCOE_CREATE_LINK_DOWN, | ||
2261 | FCOE_CREATE_LINK_UP, | ||
2262 | }; | ||
2263 | |||
2206 | /** | 2264 | /** |
2207 | * fcoe_create() - Create a fcoe interface | 2265 | * _fcoe_create() - (internal) Create a fcoe interface |
2208 | * @netdev : The net_device object the Ethernet interface to create on | 2266 | * @netdev : The net_device object the Ethernet interface to create on |
2209 | * @fip_mode: The FIP mode for this creation | 2267 | * @fip_mode: The FIP mode for this creation |
2268 | * @link_state: The ctlr link state on creation | ||
2210 | * | 2269 | * |
2211 | * Called from fcoe transport | 2270 | * Called from either the libfcoe 'create' module parameter |
2271 | * via fcoe_create or from fcoe_syfs's ctlr_create file. | ||
2212 | * | 2272 | * |
2213 | * Returns: 0 for success | 2273 | * libfcoe's 'create' module parameter is deprecated so some |
2274 | * consolidation of code can be done when that interface is | ||
2275 | * removed. | ||
2214 | */ | 2276 | */ |
2215 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | 2277 | static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode, |
2278 | enum fcoe_create_link_state link_state) | ||
2216 | { | 2279 | { |
2217 | int rc = 0; | 2280 | int rc = 0; |
2218 | struct fcoe_ctlr_device *ctlr_dev; | 2281 | struct fcoe_ctlr_device *ctlr_dev; |
@@ -2259,7 +2322,26 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2259 | /* start FIP Discovery and FLOGI */ | 2322 | /* start FIP Discovery and FLOGI */ |
2260 | lport->boot_time = jiffies; | 2323 | lport->boot_time = jiffies; |
2261 | fc_fabric_login(lport); | 2324 | fc_fabric_login(lport); |
2262 | if (!fcoe_link_ok(lport)) { | 2325 | |
2326 | /* | ||
2327 | * If the fcoe_ctlr_device is to be set to DISABLED | ||
2328 | * it must be done after the lport is added to the | ||
2329 | * hostlist, but before the rtnl_lock is released. | ||
2330 | * This is because the rtnl_lock protects the | ||
2331 | * hostlist that fcoe_device_notification uses. If | ||
2332 | * the FCoE Controller is intended to be created | ||
2333 | * DISABLED then 'enabled' needs to be considered | ||
2334 | * handling link events. 'enabled' must be set | ||
2335 | * before the lport can be found in the hostlist | ||
2336 | * when a link up event is received. | ||
2337 | */ | ||
2338 | if (link_state == FCOE_CREATE_LINK_UP) | ||
2339 | ctlr_dev->enabled = FCOE_CTLR_ENABLED; | ||
2340 | else | ||
2341 | ctlr_dev->enabled = FCOE_CTLR_DISABLED; | ||
2342 | |||
2343 | if (link_state == FCOE_CREATE_LINK_UP && | ||
2344 | !fcoe_link_ok(lport)) { | ||
2263 | rtnl_unlock(); | 2345 | rtnl_unlock(); |
2264 | fcoe_ctlr_link_up(ctlr); | 2346 | fcoe_ctlr_link_up(ctlr); |
2265 | mutex_unlock(&fcoe_config_mutex); | 2347 | mutex_unlock(&fcoe_config_mutex); |
@@ -2274,6 +2356,37 @@ out_nortnl: | |||
2274 | } | 2356 | } |
2275 | 2357 | ||
2276 | /** | 2358 | /** |
2359 | * fcoe_create() - Create a fcoe interface | ||
2360 | * @netdev : The net_device object the Ethernet interface to create on | ||
2361 | * @fip_mode: The FIP mode for this creation | ||
2362 | * | ||
2363 | * Called from fcoe transport | ||
2364 | * | ||
2365 | * Returns: 0 for success | ||
2366 | */ | ||
2367 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | ||
2368 | { | ||
2369 | return _fcoe_create(netdev, fip_mode, FCOE_CREATE_LINK_UP); | ||
2370 | } | ||
2371 | |||
2372 | /** | ||
2373 | * fcoe_ctlr_alloc() - Allocate a fcoe interface from fcoe_sysfs | ||
2374 | * @netdev: The net_device to be used by the allocated FCoE Controller | ||
2375 | * | ||
2376 | * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr | ||
2377 | * in a link_down state. The allows the user an opportunity to configure | ||
2378 | * the FCoE Controller from sysfs before enabling the FCoE Controller. | ||
2379 | * | ||
2380 | * Creating in with this routine starts the FCoE Controller in Fabric | ||
2381 | * mode. The user can change to VN2VN or another mode before enabling. | ||
2382 | */ | ||
2383 | static int fcoe_ctlr_alloc(struct net_device *netdev) | ||
2384 | { | ||
2385 | return _fcoe_create(netdev, FIP_MODE_FABRIC, | ||
2386 | FCOE_CREATE_LINK_DOWN); | ||
2387 | } | ||
2388 | |||
2389 | /** | ||
2277 | * fcoe_link_speed_update() - Update the supported and actual link speeds | 2390 | * fcoe_link_speed_update() - Update the supported and actual link speeds |
2278 | * @lport: The local port to update speeds for | 2391 | * @lport: The local port to update speeds for |
2279 | * | 2392 | * |
@@ -2374,10 +2487,13 @@ static int fcoe_reset(struct Scsi_Host *shost) | |||
2374 | struct fcoe_port *port = lport_priv(lport); | 2487 | struct fcoe_port *port = lport_priv(lport); |
2375 | struct fcoe_interface *fcoe = port->priv; | 2488 | struct fcoe_interface *fcoe = port->priv; |
2376 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); | 2489 | struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); |
2490 | struct fcoe_ctlr_device *cdev = fcoe_ctlr_to_ctlr_dev(ctlr); | ||
2377 | 2491 | ||
2378 | fcoe_ctlr_link_down(ctlr); | 2492 | fcoe_ctlr_link_down(ctlr); |
2379 | fcoe_clean_pending_queue(ctlr->lp); | 2493 | fcoe_clean_pending_queue(ctlr->lp); |
2380 | if (!fcoe_link_ok(ctlr->lp)) | 2494 | |
2495 | if (cdev->enabled != FCOE_CTLR_DISABLED && | ||
2496 | !fcoe_link_ok(ctlr->lp)) | ||
2381 | fcoe_ctlr_link_up(ctlr); | 2497 | fcoe_ctlr_link_up(ctlr); |
2382 | return 0; | 2498 | return 0; |
2383 | } | 2499 | } |
@@ -2450,6 +2566,7 @@ static struct fcoe_transport fcoe_sw_transport = { | |||
2450 | .attached = false, | 2566 | .attached = false, |
2451 | .list = LIST_HEAD_INIT(fcoe_sw_transport.list), | 2567 | .list = LIST_HEAD_INIT(fcoe_sw_transport.list), |
2452 | .match = fcoe_match, | 2568 | .match = fcoe_match, |
2569 | .alloc = fcoe_ctlr_alloc, | ||
2453 | .create = fcoe_create, | 2570 | .create = fcoe_create, |
2454 | .destroy = fcoe_destroy, | 2571 | .destroy = fcoe_destroy, |
2455 | .enable = fcoe_enable, | 2572 | .enable = fcoe_enable, |
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 2ebe03a4b51d..75834255bf07 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c | |||
@@ -2864,22 +2864,21 @@ void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev) | |||
2864 | } | 2864 | } |
2865 | EXPORT_SYMBOL(fcoe_fcf_get_selected); | 2865 | EXPORT_SYMBOL(fcoe_fcf_get_selected); |
2866 | 2866 | ||
2867 | void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev) | 2867 | void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev) |
2868 | { | 2868 | { |
2869 | struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); | 2869 | struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); |
2870 | 2870 | ||
2871 | mutex_lock(&ctlr->ctlr_mutex); | 2871 | mutex_lock(&ctlr->ctlr_mutex); |
2872 | switch (ctlr->mode) { | 2872 | switch (ctlr_dev->mode) { |
2873 | case FIP_MODE_FABRIC: | 2873 | case FIP_CONN_TYPE_VN2VN: |
2874 | ctlr_dev->mode = FIP_CONN_TYPE_FABRIC; | 2874 | ctlr->mode = FIP_MODE_VN2VN; |
2875 | break; | ||
2876 | case FIP_MODE_VN2VN: | ||
2877 | ctlr_dev->mode = FIP_CONN_TYPE_VN2VN; | ||
2878 | break; | 2875 | break; |
2876 | case FIP_CONN_TYPE_FABRIC: | ||
2879 | default: | 2877 | default: |
2880 | ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN; | 2878 | ctlr->mode = FIP_MODE_FABRIC; |
2881 | break; | 2879 | break; |
2882 | } | 2880 | } |
2881 | |||
2883 | mutex_unlock(&ctlr->ctlr_mutex); | 2882 | mutex_unlock(&ctlr->ctlr_mutex); |
2884 | } | 2883 | } |
2885 | EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode); | 2884 | EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode); |