diff options
author | Andreas Herrmann <aherrman@de.ibm.com> | 2005-11-30 20:50:36 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-12-01 16:59:47 -0500 |
commit | 2448c45965870ca9cfdb66388b4fcc93f1e12bb7 (patch) | |
tree | b028c8ad8dbb8353f7299ce5c88b54ff7cfc6433 /drivers/s390/scsi/zfcp_erp.c | |
parent | c48a29d065cfa18c3e8699f5e3a84a59ad35e062 (diff) |
[SCSI] zfcp: fix adapter initialization
Fixed various problems in opening sequence of adapters which was previously
changed with NPIV support:
o corrected handling when exchange port data function is not supported,
otherwise adapters on z900 cannot be opened anymore
o corrected setup of timer for exchange port data if called from error
recovery
o corrected check of return code of exchange config data
Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 89 |
1 files changed, 32 insertions, 57 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 8d503d9c8af7..ee7314d8c2da 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -2243,29 +2243,26 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) | |||
2243 | return retval; | 2243 | return retval; |
2244 | } | 2244 | } |
2245 | 2245 | ||
2246 | /* | ||
2247 | * function: zfcp_fsf_init | ||
2248 | * | ||
2249 | * purpose: initializes FSF operation for the specified adapter | ||
2250 | * | ||
2251 | * returns: 0 - succesful initialization of FSF operation | ||
2252 | * !0 - failed to initialize FSF operation | ||
2253 | */ | ||
2254 | static int | 2246 | static int |
2255 | 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) |
2256 | { | 2248 | { |
2257 | int xconfig, xport; | 2249 | int retval; |
2258 | 2250 | ||
2259 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 2251 | if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, |
2260 | &erp_action->adapter->status)) { | 2252 | &erp_action->adapter->status)) && |
2253 | (erp_action->adapter->adapter_features & | ||
2254 | FSF_FEATURE_HBAAPI_MANAGEMENT)) { | ||
2261 | zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); | 2255 | zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); |
2262 | atomic_set(&erp_action->adapter->erp_counter, 0); | 2256 | atomic_set(&erp_action->adapter->erp_counter, 0); |
2263 | return ZFCP_ERP_FAILED; | 2257 | return ZFCP_ERP_FAILED; |
2264 | } | 2258 | } |
2265 | 2259 | ||
2266 | xconfig = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); | 2260 | retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); |
2267 | xport = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); | 2261 | if (retval == ZFCP_ERP_FAILED) |
2268 | 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) | ||
2269 | return ZFCP_ERP_FAILED; | 2266 | return ZFCP_ERP_FAILED; |
2270 | 2267 | ||
2271 | return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); | 2268 | return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); |
@@ -2354,41 +2351,29 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) | |||
2354 | static int | 2351 | static int |
2355 | 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) |
2356 | { | 2353 | { |
2357 | int retval = ZFCP_ERP_SUCCEEDED; | 2354 | int ret; |
2358 | int retries; | 2355 | int retries; |
2359 | int sleep; | 2356 | int sleep; |
2360 | struct zfcp_adapter *adapter = erp_action->adapter; | 2357 | struct zfcp_adapter *adapter = erp_action->adapter; |
2361 | 2358 | ||
2362 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | 2359 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2363 | 2360 | ||
2364 | for (retries = 0; ; retries++) { | 2361 | retries = 0; |
2365 | ZFCP_LOG_DEBUG("Doing exchange port data\n"); | 2362 | do { |
2363 | write_lock(&adapter->erp_lock); | ||
2366 | zfcp_erp_action_to_running(erp_action); | 2364 | zfcp_erp_action_to_running(erp_action); |
2365 | write_unlock(&adapter->erp_lock); | ||
2367 | zfcp_erp_timeout_init(erp_action); | 2366 | zfcp_erp_timeout_init(erp_action); |
2368 | if (zfcp_fsf_exchange_port_data(erp_action, adapter, NULL)) { | 2367 | ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); |
2369 | retval = ZFCP_ERP_FAILED; | 2368 | if (ret == -EOPNOTSUPP) { |
2370 | debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf"); | 2369 | debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); |
2371 | ZFCP_LOG_INFO("error: initiation of exchange of " | 2370 | return ZFCP_ERP_SUCCEEDED; |
2372 | "port data failed for adapter %s\n", | 2371 | } else if (ret) { |
2373 | zfcp_get_busid_by_adapter(adapter)); | 2372 | debug_text_event(adapter->erp_dbf, 3, "a_xport_failed"); |
2374 | break; | 2373 | return ZFCP_ERP_FAILED; |
2375 | } | 2374 | } |
2376 | debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok"); | 2375 | debug_text_event(adapter->erp_dbf, 6, "a_xport_ok"); |
2377 | ZFCP_LOG_DEBUG("Xchange underway\n"); | ||
2378 | 2376 | ||
2379 | /* | ||
2380 | * Why this works: | ||
2381 | * Both the normal completion handler as well as the timeout | ||
2382 | * handler will do an 'up' when the 'exchange port data' | ||
2383 | * request completes or times out. Thus, the signal to go on | ||
2384 | * won't be lost utilizing this semaphore. | ||
2385 | * Furthermore, this 'adapter_reopen' action is | ||
2386 | * guaranteed to be the only action being there (highest action | ||
2387 | * which prevents other actions from being created). | ||
2388 | * Resulting from that, the wake signal recognized here | ||
2389 | * _must_ be the one belonging to the 'exchange port | ||
2390 | * data' request. | ||
2391 | */ | ||
2392 | down(&adapter->erp_ready_sem); | 2377 | down(&adapter->erp_ready_sem); |
2393 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { | 2378 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
2394 | ZFCP_LOG_INFO("error: exchange of port data " | 2379 | ZFCP_LOG_INFO("error: exchange of port data " |
@@ -2396,29 +2381,19 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) | |||
2396 | zfcp_get_busid_by_adapter(adapter)); | 2381 | zfcp_get_busid_by_adapter(adapter)); |
2397 | break; | 2382 | break; |
2398 | } | 2383 | } |
2399 | |||
2400 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 2384 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, |
2401 | &adapter->status)) | 2385 | &adapter->status)) |
2402 | break; | 2386 | break; |
2403 | 2387 | ||
2404 | ZFCP_LOG_DEBUG("host connection still initialising... " | 2388 | if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) { |
2405 | "waiting and retrying...\n"); | 2389 | sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP; |
2406 | /* sleep a little bit before retry */ | 2390 | retries++; |
2407 | sleep = retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES ? | 2391 | } else |
2408 | ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP : | 2392 | sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP; |
2409 | ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP; | 2393 | schedule_timeout(sleep); |
2410 | msleep(jiffies_to_msecs(sleep)); | 2394 | } while (1); |
2411 | } | ||
2412 | |||
2413 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | ||
2414 | &adapter->status)) { | ||
2415 | ZFCP_LOG_INFO("error: exchange of port data for " | ||
2416 | "adapter %s failed\n", | ||
2417 | zfcp_get_busid_by_adapter(adapter)); | ||
2418 | retval = ZFCP_ERP_FAILED; | ||
2419 | } | ||
2420 | 2395 | ||
2421 | return retval; | 2396 | return ZFCP_ERP_SUCCEEDED; |
2422 | } | 2397 | } |
2423 | 2398 | ||
2424 | /* | 2399 | /* |