aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c69
1 files changed, 52 insertions, 17 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index e65262070749..1221b760f49e 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2383,24 +2383,30 @@ out:
2383 * @cmd: scsi command to abort 2383 * @cmd: scsi command to abort
2384 * 2384 *
2385 * Returns: 2385 * Returns:
2386 * SUCCESS / FAILED 2386 * SUCCESS / FAST_IO_FAIL / FAILED
2387 **/ 2387 **/
2388static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) 2388static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd)
2389{ 2389{
2390 struct scsi_device *sdev = cmd->device; 2390 struct scsi_device *sdev = cmd->device;
2391 struct ibmvfc_host *vhost = shost_priv(sdev->host); 2391 struct ibmvfc_host *vhost = shost_priv(sdev->host);
2392 int cancel_rc, abort_rc; 2392 int cancel_rc, block_rc, abort_rc = 0;
2393 int rc = FAILED; 2393 int rc = FAILED;
2394 2394
2395 ENTER; 2395 ENTER;
2396 fc_block_scsi_eh(cmd); 2396 block_rc = fc_block_scsi_eh(cmd);
2397 ibmvfc_wait_while_resetting(vhost); 2397 ibmvfc_wait_while_resetting(vhost);
2398 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); 2398 if (block_rc != FAST_IO_FAIL) {
2399 abort_rc = ibmvfc_abort_task_set(sdev); 2399 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET);
2400 abort_rc = ibmvfc_abort_task_set(sdev);
2401 } else
2402 cancel_rc = ibmvfc_cancel_all(sdev, 0);
2400 2403
2401 if (!cancel_rc && !abort_rc) 2404 if (!cancel_rc && !abort_rc)
2402 rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); 2405 rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun);
2403 2406
2407 if (block_rc == FAST_IO_FAIL && rc != FAILED)
2408 rc = FAST_IO_FAIL;
2409
2404 LEAVE; 2410 LEAVE;
2405 return rc; 2411 return rc;
2406} 2412}
@@ -2410,29 +2416,47 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd)
2410 * @cmd: scsi command struct 2416 * @cmd: scsi command struct
2411 * 2417 *
2412 * Returns: 2418 * Returns:
2413 * SUCCESS / FAILED 2419 * SUCCESS / FAST_IO_FAIL / FAILED
2414 **/ 2420 **/
2415static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd) 2421static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd)
2416{ 2422{
2417 struct scsi_device *sdev = cmd->device; 2423 struct scsi_device *sdev = cmd->device;
2418 struct ibmvfc_host *vhost = shost_priv(sdev->host); 2424 struct ibmvfc_host *vhost = shost_priv(sdev->host);
2419 int cancel_rc, reset_rc; 2425 int cancel_rc, block_rc, reset_rc = 0;
2420 int rc = FAILED; 2426 int rc = FAILED;
2421 2427
2422 ENTER; 2428 ENTER;
2423 fc_block_scsi_eh(cmd); 2429 block_rc = fc_block_scsi_eh(cmd);
2424 ibmvfc_wait_while_resetting(vhost); 2430 ibmvfc_wait_while_resetting(vhost);
2425 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET); 2431 if (block_rc != FAST_IO_FAIL) {
2426 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN"); 2432 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET);
2433 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN");
2434 } else
2435 cancel_rc = ibmvfc_cancel_all(sdev, 0);
2427 2436
2428 if (!cancel_rc && !reset_rc) 2437 if (!cancel_rc && !reset_rc)
2429 rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); 2438 rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun);
2430 2439
2440 if (block_rc == FAST_IO_FAIL && rc != FAILED)
2441 rc = FAST_IO_FAIL;
2442
2431 LEAVE; 2443 LEAVE;
2432 return rc; 2444 return rc;
2433} 2445}
2434 2446
2435/** 2447/**
2448 * ibmvfc_dev_cancel_all_noreset - Device iterated cancel all function
2449 * @sdev: scsi device struct
2450 * @data: return code
2451 *
2452 **/
2453static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data)
2454{
2455 unsigned long *rc = data;
2456 *rc |= ibmvfc_cancel_all(sdev, 0);
2457}
2458
2459/**
2436 * ibmvfc_dev_cancel_all_reset - Device iterated cancel all function 2460 * ibmvfc_dev_cancel_all_reset - Device iterated cancel all function
2437 * @sdev: scsi device struct 2461 * @sdev: scsi device struct
2438 * @data: return code 2462 * @data: return code
@@ -2449,26 +2473,33 @@ static void ibmvfc_dev_cancel_all_reset(struct scsi_device *sdev, void *data)
2449 * @cmd: scsi command struct 2473 * @cmd: scsi command struct
2450 * 2474 *
2451 * Returns: 2475 * Returns:
2452 * SUCCESS / FAILED 2476 * SUCCESS / FAST_IO_FAIL / FAILED
2453 **/ 2477 **/
2454static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd) 2478static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
2455{ 2479{
2456 struct scsi_device *sdev = cmd->device; 2480 struct scsi_device *sdev = cmd->device;
2457 struct ibmvfc_host *vhost = shost_priv(sdev->host); 2481 struct ibmvfc_host *vhost = shost_priv(sdev->host);
2458 struct scsi_target *starget = scsi_target(sdev); 2482 struct scsi_target *starget = scsi_target(sdev);
2459 int reset_rc; 2483 int block_rc;
2484 int reset_rc = 0;
2460 int rc = FAILED; 2485 int rc = FAILED;
2461 unsigned long cancel_rc = 0; 2486 unsigned long cancel_rc = 0;
2462 2487
2463 ENTER; 2488 ENTER;
2464 fc_block_scsi_eh(cmd); 2489 block_rc = fc_block_scsi_eh(cmd);
2465 ibmvfc_wait_while_resetting(vhost); 2490 ibmvfc_wait_while_resetting(vhost);
2466 starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset); 2491 if (block_rc != FAST_IO_FAIL) {
2467 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target"); 2492 starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset);
2493 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target");
2494 } else
2495 starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_noreset);
2468 2496
2469 if (!cancel_rc && !reset_rc) 2497 if (!cancel_rc && !reset_rc)
2470 rc = ibmvfc_wait_for_ops(vhost, starget, ibmvfc_match_target); 2498 rc = ibmvfc_wait_for_ops(vhost, starget, ibmvfc_match_target);
2471 2499
2500 if (block_rc == FAST_IO_FAIL && rc != FAILED)
2501 rc = FAST_IO_FAIL;
2502
2472 LEAVE; 2503 LEAVE;
2473 return rc; 2504 return rc;
2474} 2505}
@@ -2480,12 +2511,16 @@ static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
2480 **/ 2511 **/
2481static int ibmvfc_eh_host_reset_handler(struct scsi_cmnd *cmd) 2512static int ibmvfc_eh_host_reset_handler(struct scsi_cmnd *cmd)
2482{ 2513{
2483 int rc; 2514 int rc, block_rc;
2484 struct ibmvfc_host *vhost = shost_priv(cmd->device->host); 2515 struct ibmvfc_host *vhost = shost_priv(cmd->device->host);
2485 2516
2486 fc_block_scsi_eh(cmd); 2517 block_rc = fc_block_scsi_eh(cmd);
2487 dev_err(vhost->dev, "Resetting connection due to error recovery\n"); 2518 dev_err(vhost->dev, "Resetting connection due to error recovery\n");
2488 rc = ibmvfc_issue_fc_host_lip(vhost->host); 2519 rc = ibmvfc_issue_fc_host_lip(vhost->host);
2520
2521 if (block_rc == FAST_IO_FAIL)
2522 return FAST_IO_FAIL;
2523
2489 return rc ? FAILED : SUCCESS; 2524 return rc ? FAILED : SUCCESS;
2490} 2525}
2491 2526