aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c89
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c60
2 files changed, 64 insertions, 85 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 */
2254static int 2246static int
2255zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) 2247zfcp_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)
2354static int 2351static int
2355zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) 2352zfcp_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/*
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 3b0fc1163f5f..fbc81b012919 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2191,13 +2191,10 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
2191 return -EOPNOTSUPP; 2191 return -EOPNOTSUPP;
2192 } 2192 }
2193 2193
2194 timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
2195 if (!timer)
2196 return -ENOMEM;
2197
2198 /* setup new FSF request */ 2194 /* setup new FSF request */
2199 retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 2195 retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
2200 0, 0, &lock_flags, &fsf_req); 2196 erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0,
2197 0, &lock_flags, &fsf_req);
2201 if (retval < 0) { 2198 if (retval < 0) {
2202 ZFCP_LOG_INFO("error: Out of resources. Could not create an " 2199 ZFCP_LOG_INFO("error: Out of resources. Could not create an "
2203 "exchange port data request for" 2200 "exchange port data request for"
@@ -2205,25 +2202,33 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
2205 zfcp_get_busid_by_adapter(adapter)); 2202 zfcp_get_busid_by_adapter(adapter));
2206 write_unlock_irqrestore(&adapter->request_queue.queue_lock, 2203 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2207 lock_flags); 2204 lock_flags);
2208 goto out; 2205 return retval;
2209 }
2210
2211 if (erp_action) {
2212 erp_action->fsf_req = fsf_req;
2213 fsf_req->erp_action = erp_action;
2214 } 2206 }
2215 2207
2216 if (data) 2208 if (data)
2217 fsf_req->data = (unsigned long) data; 2209 fsf_req->data = (unsigned long) data;
2218 2210
2219 sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); 2211 sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
2220 sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; 2212 sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
2221 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; 2213 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
2222 2214
2223 init_timer(timer); 2215 if (erp_action) {
2224 timer->function = zfcp_fsf_request_timeout_handler; 2216 erp_action->fsf_req = fsf_req;
2225 timer->data = (unsigned long) adapter; 2217 fsf_req->erp_action = erp_action;
2226 timer->expires = ZFCP_FSF_REQUEST_TIMEOUT; 2218 timer = &erp_action->timer;
2219 } else {
2220 timer = kmalloc(sizeof(struct timer_list), GFP_ATOMIC);
2221 if (!timer) {
2222 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2223 lock_flags);
2224 zfcp_fsf_req_free(fsf_req);
2225 return -ENOMEM;
2226 }
2227 init_timer(timer);
2228 timer->function = zfcp_fsf_request_timeout_handler;
2229 timer->data = (unsigned long) adapter;
2230 timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
2231 }
2227 2232
2228 retval = zfcp_fsf_req_send(fsf_req, timer); 2233 retval = zfcp_fsf_req_send(fsf_req, timer);
2229 if (retval) { 2234 if (retval) {
@@ -2233,23 +2238,22 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
2233 zfcp_fsf_req_free(fsf_req); 2238 zfcp_fsf_req_free(fsf_req);
2234 if (erp_action) 2239 if (erp_action)
2235 erp_action->fsf_req = NULL; 2240 erp_action->fsf_req = NULL;
2241 else
2242 kfree(timer);
2236 write_unlock_irqrestore(&adapter->request_queue.queue_lock, 2243 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2237 lock_flags); 2244 lock_flags);
2238 goto out; 2245 return retval;
2239 } 2246 }
2240 2247
2241 ZFCP_LOG_DEBUG("Exchange Port Data request initiated (adapter %s)\n", 2248 write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
2242 zfcp_get_busid_by_adapter(adapter));
2243
2244 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2245 lock_flags);
2246 2249
2247 wait_event(fsf_req->completion_wq, 2250 if (!erp_action) {
2248 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); 2251 wait_event(fsf_req->completion_wq,
2249 del_timer_sync(timer); 2252 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
2250 zfcp_fsf_req_free(fsf_req); 2253 del_timer_sync(timer);
2251 out: 2254 zfcp_fsf_req_free(fsf_req);
2252 kfree(timer); 2255 kfree(timer);
2256 }
2253 return retval; 2257 return retval;
2254} 2258}
2255 2259