aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_qdio.c
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2010-07-16 09:37:43 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:48:58 -0400
commit339f4f4eab80caa6cf0d39fb057ad6ddb84ba91e (patch)
tree495dc5a18c128d3e802a8b1914f978bf4262ac3d /drivers/s390/scsi/zfcp_qdio.c
parentef3eb71d8ba4fd9d48c5f9310bc9d90ca00323b4 (diff)
[SCSI] zfcp: Trigger logging in the FCP channel on qdio error conditions
Exploit the cio siosl function to trigger logging in the FCP channel on qdio error conditions. Add a helper function in zfcp_qdio to ensure that tracing is only triggered once before calling qdio_shutdown. Trigger in zfcp for hardware logs are: - timeout for FSF requests to the FCP channel - "no recommendation" status from FCP channel - invalid FSF protocol status - stalled outbound queue - unknown request id on inbound queue - QDIO_ERROR_SLSB_STATE All of the above triggers run from the Linux qdio softirq context, so no additional synchronization is necessary for the handling of the ZFCP_STATUS_ADAPTER_SIOSL_ISSUED flag. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390/scsi/zfcp_qdio.c')
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index aceced8ec7e4..b2635759721c 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -30,12 +30,15 @@ static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
30 return 0; 30 return 0;
31} 31}
32 32
33static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id) 33static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
34 unsigned int qdio_err)
34{ 35{
35 struct zfcp_adapter *adapter = qdio->adapter; 36 struct zfcp_adapter *adapter = qdio->adapter;
36 37
37 dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n"); 38 dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
38 39
40 if (qdio_err & QDIO_ERROR_SLSB_STATE)
41 zfcp_qdio_siosl(adapter);
39 zfcp_erp_adapter_reopen(adapter, 42 zfcp_erp_adapter_reopen(adapter,
40 ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | 43 ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
41 ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL); 44 ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL);
@@ -74,7 +77,7 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
74 77
75 if (unlikely(qdio_err)) { 78 if (unlikely(qdio_err)) {
76 zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count); 79 zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
77 zfcp_qdio_handler_error(qdio, "qdireq1"); 80 zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err);
78 return; 81 return;
79 } 82 }
80 83
@@ -95,7 +98,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
95 98
96 if (unlikely(qdio_err)) { 99 if (unlikely(qdio_err)) {
97 zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count); 100 zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
98 zfcp_qdio_handler_error(qdio, "qdires1"); 101 zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
99 return; 102 return;
100 } 103 }
101 104
@@ -361,6 +364,9 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
361 if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP) 364 if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)
362 return -EIO; 365 return -EIO;
363 366
367 atomic_clear_mask(ZFCP_STATUS_ADAPTER_SIOSL_ISSUED,
368 &qdio->adapter->status);
369
364 zfcp_qdio_setup_init_data(&init_data, qdio); 370 zfcp_qdio_setup_init_data(&init_data, qdio);
365 371
366 if (qdio_establish(&init_data)) 372 if (qdio_establish(&init_data))
@@ -440,3 +446,26 @@ int zfcp_qdio_setup(struct zfcp_adapter *adapter)
440 return 0; 446 return 0;
441} 447}
442 448
449/**
450 * zfcp_qdio_siosl - Trigger logging in FCP channel
451 * @adapter: The zfcp_adapter where to trigger logging
452 *
453 * Call the cio siosl function to trigger hardware logging. This
454 * wrapper function sets a flag to ensure hardware logging is only
455 * triggered once before going through qdio shutdown.
456 *
457 * The triggers are always run from qdio tasklet context, so no
458 * additional synchronization is necessary.
459 */
460void zfcp_qdio_siosl(struct zfcp_adapter *adapter)
461{
462 int rc;
463
464 if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_SIOSL_ISSUED)
465 return;
466
467 rc = ccw_device_siosl(adapter->ccw_device);
468 if (!rc)
469 atomic_set_mask(ZFCP_STATUS_ADAPTER_SIOSL_ISSUED,
470 &adapter->status);
471}