diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 739356a5c123..5ae1d497e5ed 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright IBM Corporation 2002, 2008 | 6 | * Copyright IBM Corporation 2002, 2008 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/blktrace_api.h> | ||
9 | #include "zfcp_ext.h" | 10 | #include "zfcp_ext.h" |
10 | 11 | ||
11 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 12 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
@@ -777,6 +778,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | |||
777 | list_add_tail(&req->list, &adapter->req_list[idx]); | 778 | list_add_tail(&req->list, &adapter->req_list[idx]); |
778 | spin_unlock(&adapter->req_list_lock); | 779 | spin_unlock(&adapter->req_list_lock); |
779 | 780 | ||
781 | req->qdio_outb_usage = atomic_read(&req_q->count); | ||
780 | req->issued = get_clock(); | 782 | req->issued = get_clock(); |
781 | if (zfcp_qdio_send(req)) { | 783 | if (zfcp_qdio_send(req)) { |
782 | /* Queues are down..... */ | 784 | /* Queues are down..... */ |
@@ -2082,6 +2084,36 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req) | |||
2082 | spin_unlock_irqrestore(&unit->latencies.lock, flags); | 2084 | spin_unlock_irqrestore(&unit->latencies.lock, flags); |
2083 | } | 2085 | } |
2084 | 2086 | ||
2087 | #ifdef CONFIG_BLK_DEV_IO_TRACE | ||
2088 | static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | ||
2089 | { | ||
2090 | struct fsf_qual_latency_info *lat_inf; | ||
2091 | struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | ||
2092 | struct request *req = scsi_cmnd->request; | ||
2093 | struct zfcp_blk_drv_data trace; | ||
2094 | int ticks = fsf_req->adapter->timer_ticks; | ||
2095 | |||
2096 | trace.flags = 0; | ||
2097 | trace.magic = ZFCP_BLK_DRV_DATA_MAGIC; | ||
2098 | if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) { | ||
2099 | trace.flags |= ZFCP_BLK_LAT_VALID; | ||
2100 | lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info; | ||
2101 | trace.channel_lat = lat_inf->channel_lat * ticks; | ||
2102 | trace.fabric_lat = lat_inf->fabric_lat * ticks; | ||
2103 | } | ||
2104 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | ||
2105 | trace.flags |= ZFCP_BLK_REQ_ERROR; | ||
2106 | trace.inb_usage = fsf_req->qdio_inb_usage; | ||
2107 | trace.outb_usage = fsf_req->qdio_outb_usage; | ||
2108 | |||
2109 | blk_add_driver_data(req->q, req, &trace, sizeof(trace)); | ||
2110 | } | ||
2111 | #else | ||
2112 | static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | ||
2113 | { | ||
2114 | } | ||
2115 | #endif | ||
2116 | |||
2085 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | 2117 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) |
2086 | { | 2118 | { |
2087 | struct scsi_cmnd *scpnt = req->data; | 2119 | struct scsi_cmnd *scpnt = req->data; |
@@ -2114,6 +2146,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | |||
2114 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) | 2146 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) |
2115 | zfcp_fsf_req_latency(req); | 2147 | zfcp_fsf_req_latency(req); |
2116 | 2148 | ||
2149 | zfcp_fsf_trace_latency(req); | ||
2150 | |||
2117 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { | 2151 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { |
2118 | if (fcp_rsp_info[3] == RSP_CODE_GOOD) | 2152 | if (fcp_rsp_info[3] == RSP_CODE_GOOD) |
2119 | set_host_byte(scpnt, DID_OK); | 2153 | set_host_byte(scpnt, DID_OK); |