diff options
| author | Tony Luck <tony.luck@intel.com> | 2005-12-05 14:50:17 -0500 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2005-12-05 14:50:17 -0500 |
| commit | 3e356b2660eda9da7776144cbc0a038c93dcb335 (patch) | |
| tree | 378a38636f6b67a5f092a73850223d11cdfb5ff5 /drivers/s390/scsi/zfcp_erp.c | |
| parent | 05f70395c642bed0300bc1955bfa8c0f93de2bc2 (diff) | |
| parent | e4f5c82a92c2a546a16af1614114eec19120e40a (diff) | |
Auto-update from upstream
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 | /* |
