diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 94 |
1 files changed, 32 insertions, 62 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 023f4e558ae4..ee7314d8c2da 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -1071,11 +1071,6 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter) | |||
1071 | 1071 | ||
1072 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); | 1072 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); |
1073 | 1073 | ||
1074 | rwlock_init(&adapter->erp_lock); | ||
1075 | INIT_LIST_HEAD(&adapter->erp_ready_head); | ||
1076 | INIT_LIST_HEAD(&adapter->erp_running_head); | ||
1077 | sema_init(&adapter->erp_ready_sem, 0); | ||
1078 | |||
1079 | retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); | 1074 | retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); |
1080 | if (retval < 0) { | 1075 | if (retval < 0) { |
1081 | ZFCP_LOG_NORMAL("error: creation of erp thread failed for " | 1076 | ZFCP_LOG_NORMAL("error: creation of erp thread failed for " |
@@ -2248,29 +2243,26 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) | |||
2248 | return retval; | 2243 | return retval; |
2249 | } | 2244 | } |
2250 | 2245 | ||
2251 | /* | ||
2252 | * function: zfcp_fsf_init | ||
2253 | * | ||
2254 | * purpose: initializes FSF operation for the specified adapter | ||
2255 | * | ||
2256 | * returns: 0 - succesful initialization of FSF operation | ||
2257 | * !0 - failed to initialize FSF operation | ||
2258 | */ | ||
2259 | static int | 2246 | static int |
2260 | zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) | 2247 | zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) |
2261 | { | 2248 | { |
2262 | int xconfig, xport; | 2249 | int retval; |
2263 | 2250 | ||
2264 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 2251 | if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, |
2265 | &erp_action->adapter->status)) { | 2252 | &erp_action->adapter->status)) && |
2253 | (erp_action->adapter->adapter_features & | ||
2254 | FSF_FEATURE_HBAAPI_MANAGEMENT)) { | ||
2266 | zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); | 2255 | zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); |
2267 | atomic_set(&erp_action->adapter->erp_counter, 0); | 2256 | atomic_set(&erp_action->adapter->erp_counter, 0); |
2268 | return ZFCP_ERP_FAILED; | 2257 | return ZFCP_ERP_FAILED; |
2269 | } | 2258 | } |
2270 | 2259 | ||
2271 | xconfig = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); | 2260 | retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); |
2272 | xport = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); | 2261 | if (retval == ZFCP_ERP_FAILED) |
2273 | if ((xconfig == ZFCP_ERP_FAILED) || (xport == ZFCP_ERP_FAILED)) | 2262 | return ZFCP_ERP_FAILED; |
2263 | |||
2264 | retval = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); | ||
2265 | if (retval == ZFCP_ERP_FAILED) | ||
2274 | return ZFCP_ERP_FAILED; | 2266 | return ZFCP_ERP_FAILED; |
2275 | 2267 | ||
2276 | return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); | 2268 | return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); |
@@ -2359,41 +2351,29 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) | |||
2359 | static int | 2351 | static int |
2360 | zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) | 2352 | zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) |
2361 | { | 2353 | { |
2362 | int retval = ZFCP_ERP_SUCCEEDED; | 2354 | int ret; |
2363 | int retries; | 2355 | int retries; |
2364 | int sleep; | 2356 | int sleep; |
2365 | struct zfcp_adapter *adapter = erp_action->adapter; | 2357 | struct zfcp_adapter *adapter = erp_action->adapter; |
2366 | 2358 | ||
2367 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | 2359 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2368 | 2360 | ||
2369 | for (retries = 0; ; retries++) { | 2361 | retries = 0; |
2370 | ZFCP_LOG_DEBUG("Doing exchange port data\n"); | 2362 | do { |
2363 | write_lock(&adapter->erp_lock); | ||
2371 | zfcp_erp_action_to_running(erp_action); | 2364 | zfcp_erp_action_to_running(erp_action); |
2365 | write_unlock(&adapter->erp_lock); | ||
2372 | zfcp_erp_timeout_init(erp_action); | 2366 | zfcp_erp_timeout_init(erp_action); |
2373 | if (zfcp_fsf_exchange_port_data(erp_action, adapter, NULL)) { | 2367 | ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); |
2374 | retval = ZFCP_ERP_FAILED; | 2368 | if (ret == -EOPNOTSUPP) { |
2375 | debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf"); | 2369 | debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); |
2376 | ZFCP_LOG_INFO("error: initiation of exchange of " | 2370 | return ZFCP_ERP_SUCCEEDED; |
2377 | "port data failed for adapter %s\n", | 2371 | } else if (ret) { |
2378 | zfcp_get_busid_by_adapter(adapter)); | 2372 | debug_text_event(adapter->erp_dbf, 3, "a_xport_failed"); |
2379 | break; | 2373 | return ZFCP_ERP_FAILED; |
2380 | } | 2374 | } |
2381 | debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok"); | 2375 | debug_text_event(adapter->erp_dbf, 6, "a_xport_ok"); |
2382 | ZFCP_LOG_DEBUG("Xchange underway\n"); | ||
2383 | 2376 | ||
2384 | /* | ||
2385 | * Why this works: | ||
2386 | * Both the normal completion handler as well as the timeout | ||
2387 | * handler will do an 'up' when the 'exchange port data' | ||
2388 | * request completes or times out. Thus, the signal to go on | ||
2389 | * won't be lost utilizing this semaphore. | ||
2390 | * Furthermore, this 'adapter_reopen' action is | ||
2391 | * guaranteed to be the only action being there (highest action | ||
2392 | * which prevents other actions from being created). | ||
2393 | * Resulting from that, the wake signal recognized here | ||
2394 | * _must_ be the one belonging to the 'exchange port | ||
2395 | * data' request. | ||
2396 | */ | ||
2397 | down(&adapter->erp_ready_sem); | 2377 | down(&adapter->erp_ready_sem); |
2398 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { | 2378 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
2399 | ZFCP_LOG_INFO("error: exchange of port data " | 2379 | ZFCP_LOG_INFO("error: exchange of port data " |
@@ -2401,29 +2381,19 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) | |||
2401 | zfcp_get_busid_by_adapter(adapter)); | 2381 | zfcp_get_busid_by_adapter(adapter)); |
2402 | break; | 2382 | break; |
2403 | } | 2383 | } |
2404 | |||
2405 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 2384 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, |
2406 | &adapter->status)) | 2385 | &adapter->status)) |
2407 | break; | 2386 | break; |
2408 | 2387 | ||
2409 | ZFCP_LOG_DEBUG("host connection still initialising... " | 2388 | if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) { |
2410 | "waiting and retrying...\n"); | 2389 | sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP; |
2411 | /* sleep a little bit before retry */ | 2390 | retries++; |
2412 | sleep = retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES ? | 2391 | } else |
2413 | ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP : | 2392 | sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP; |
2414 | ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP; | 2393 | schedule_timeout(sleep); |
2415 | msleep(jiffies_to_msecs(sleep)); | 2394 | } while (1); |
2416 | } | ||
2417 | |||
2418 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | ||
2419 | &adapter->status)) { | ||
2420 | ZFCP_LOG_INFO("error: exchange of port data for " | ||
2421 | "adapter %s failed\n", | ||
2422 | zfcp_get_busid_by_adapter(adapter)); | ||
2423 | retval = ZFCP_ERP_FAILED; | ||
2424 | } | ||
2425 | 2395 | ||
2426 | return retval; | 2396 | return ZFCP_ERP_SUCCEEDED; |
2427 | } | 2397 | } |
2428 | 2398 | ||
2429 | /* | 2399 | /* |